Releases: 1fairyfox/random-ai-prompt
Release list
v2.60.3
Random AI prompt + image generator for the Stable Diffusion WebUI -- a CLI and a local web UI.
Pre-release software. Provided as-is under Apache-2.0.
What's new in this release
Changelog — August 2026
Newest entry on top.
2026-08-02 — security (2.60.3) — remediate the OpenSSF Scorecard (6.7 → projected ~7.4)
Closed the compliance audit's headline finding (ship-contract Scorecard below the 7.0 floor) by
clearing the dominant lever — the Vulnerabilities check (was 0). Fixed everything fixable:
root + targets/web npm audit fix (→ 0 vulns each), and targets/mobile pinned postcss ^8.5.25
- brace-expansion
^2.0.2viaoverrides. Documented + filtered the genuine-no-fix advisories
viaosv-scanner.tomlnext to each manifest (the mechanism Scorecard's Vulnerabilities check honors):
17 unmaintained Tauri-v2-Linux gtk3-rs/glib/proc-macro/unic Rust crates (confirmed no-fix by
cargo audit) intargets/web-shell/, and 1 build-time-only Expouuidadvisory intargets/mobile/.
Verified with the real tool — osv-scanner v2.4.0 reports "No issues found" — so the check moves
0 → 10, lifting the score to ~7.4.npm testgreen (375 + 430 + 122). PATCH 2.60.2 → 2.60.3. The public
api.securityscorecards.devnumber refreshes on OSSF's weekly rescan. Report:
../fairyfox-reports/2026-08-02-scorecard-remediation.md.
2026-08-02 — docs/notes — fairyfox: first full standards compliance audit
Ran the first full compliance audit (the gap seeded in the 2026-08-02 adoption). Walked every
adopted standard's ## Verify and recorded a dated per-standard result in
../reference/adoption-manifest.md: 25/30 applicable standards
implemented (34 rows − 4 N-A; 5 non-implemented), the rest honest dated gaps. Headline finding: the ship-contract's OpenSSF Scorecard
is 6.7, below the 7.0 floor — verified against the live api.securityscorecards.dev (not the badge).
The dominant lever is Vulnerabilities = 0 (27 known, mostly RUSTSEC advisories in the Tauri/Rust
desktop deps); several other checks (Code-Review, Contributors, Branch-Protection) are structurally low
for a solo 0-approval repo. Also partial: supply-chain (releases signed but no provenance), docs-site
(chrome 2.2.1 → 2.3.0, browser-gated), docker (no Dockerfile yet), mandate-ledger (no ledger triggered).
Fixed in-pass: pruned 5 stale Dependabot branches → the remote carries only main/dev
(repo-hygiene clean). Also flags a date-accuracy correction: earlier artifacts in this effort were
mis-dated 2026-07-25 (hub-commit date); the real date is 2026-08-02. Report:
../fairyfox-reports/2026-08-02-compliance-audit.md.
No VERSION bump (notes/docs only).
How to get it
Prefer not to build? Download a pre-built edition:
- Desktop app -- Windows
.msi/.exe(or a portable.zip), macOS.dmg, Linux.AppImage/.deb(attached below). Self-contained; nothing to install first. random-ai-prompt-2.60.3-online.zip-- the online edition as static files; host it anywhere, or just use https://prompt.fairyfox.io.random-ai-prompt-2.60.3.tar.gz-- source tarball (run with Node 24:npm installthennpm start).random-ai-prompt-2.60.3-docs.zip-- the generated documentation site.
What's Changed
- docs: first full standards compliance audit by @1fairyfox in #65
- Release v2.60.3 — Scorecard security remediation by @1fairyfox in #66
Full Changelog: v2.60.2...v2.60.3
v2.60.2
Random AI prompt + image generator for the Stable Diffusion WebUI -- a CLI and a local web UI.
Pre-release software. Provided as-is under Apache-2.0.
What's new in this release
2026-07-25 — deps (2.60.2) — merge all four pending Dependabot groups (#56, #57, #59, #60)
Closed every open Dependabot PR during the release, verified against the project's own dev gate.
Dependabot regenerated the groups mid-release (#59/#60 superseded #56/#57 with newer targets), so all
four were folded into dev, superset-wins. Final merged state — engine group: compromise
14.15.1→14.16.0, @playwright/test 1.61.1→1.62.0, eslint 10.6.0→10.8.0, prettier
3.9.4→3.9.6, stylelint 17.14.0→17.14.1; github-actions group: action-version pins bumped
across all nine workflow files (ci, codeql, scorecard, sonar, pages, release,
netlify-deploy, branch-sync, visual-baselines) — e.g. actions/checkout v7.0.1,
actions/setup-node v7.0.0, actions/setup-java v5.6.0 — no code impact. Merged into dev with
--no-ff and verified locally with npm install + npm test green (the project's dev gate; CI
runs only on the main PR). PATCH bump 2.60.1 → 2.60.2.
2026-07-25 — docs/notes — fairyfox: adopt the hub 0.20.2 → 1.6.1 standards span
Ran the fairyfox adopting-updates flow against hub 1.6.1 (the mirror had been force-pushed and
renumbered from 0.20.x). Adopted the whole span under the standing adopt-standards-by-default grant:
seeded the project's first notes/reference/adoption-manifest.md (the 0.21.0 linchpin — a per-
standard record where copied-only ≠ adopted and no Standards adopted ✅ is written without a
backing row); added four new-standard notes — checklists-are-contracts, mandate-ledger, docker,
readme; folded the material changes into planning (phase-by-default), engineering-quality (the
ship contract — Scorecard ≥ 7.0 floor, tech-debt removal, PR triage), git-workflow (the pre-release
manifest gate), coins (base counter mandatory), and compliance (matrix rows); and wired
checklists-are-contracts / mandate-ledger / the manifest / phase-by-default into CLAUDE.md Default
Workflow step 0. The README was brought to the new readme standard: a worded 📖 Documentation
link near the top, an organized Get it section (Try it live / Download / Source), and a mesh
footer; its badge block already carried all 20 canonical badges in order (adopted as a filing act).
Browser-gated docs-site visual work — the chrome bump 2.2.1 → 2.3.0 plus the 1.4.0 subnav / on-
site Notes / coins-presence requirements — is deferred as a named tracked gap in the manifest, per
the runbook's "phase a mixed adoption." Notes/docs + README only — no VERSION bump. Full account:
fairyfox-reports/2026-07-25-adopting-updates.md.
2026-07-19 — docs-site — fairyfox: add the coins counter to the docs chrome
The docs-site shared chrome gained the coins reading-engagement counter (a button beside the reader
"Aa"), correcting an earlier miscall that filed coins as out-of-scope — it ships as part of the chrome
this node already wears, and the docs site is same-origin under fairyfox.io/<key>/, so it shares the
hub wallet. Verified the rest of the chrome is already current at bundle 2.2.1 (reader constants + nav
match the master); coins was the sole gap. assets/docs-theme/modules/coins.js is the master coins.js
vendored verbatim (the earning engine must not be reimplemented), injected after initReader() so
its button sits left of "Aa"; theme/coins.css carries the button/panel/pop/read-time styles on the
project tokens; notes/reference/coins.md + a compliance row document it. Same-origin with the hub, so
the hub /legal/coins/ page covers the fairyfox:coins:a disclosure and no project legal page changes.
Notes/docs-theme only — no VERSION bump. Verified: npm run docs, check:docs, lint/format:check.
2026-07-19 — docs — fairyfox: adopt six new mesh standards as reference notes
A fairyfox system update check refreshed the hub mirror to 0.20.2 and found six standards that
postdate this node's last adoption — all already practiced here but with no first-class home in the
tree. Under the hub's standing adopt-standards-by-default authorization (owner-confirmed scope: adopt
all), added notes/reference/{engineering-quality,planning,research-capture,working-rhythm, self-hosted-assets,agent-tooling}.md, each mapping the hub canonical to how this project already
satisfies it (working-agreements, the Default Workflow, self-hosted fonts, PowerShell/file-tools,
notes-first). Wired in: a plan-before-execute step 0 in the CLAUDE.md Default Workflow, rows for
all six in the compliance audit matrix, and index/folder-map entries in
notes/README.md. Notes-only — no VERSION bump. Verification: check:docs (461 links), format:check,
smoke all green. Process reports: notes/fairyfox-reports/2026-07-19-{check-for-updates,adopting-updates}.md.
How to get it
Prefer not to build? Download a pre-built edition:
- Desktop app -- Windows
.msi/.exe(or a portable.zip), macOS.dmg, Linux.AppImage/.deb(attached below). Self-contained; nothing to install first. random-ai-prompt-2.60.2-online.zip-- the online edition as static files; host it anywhere, or just use https://prompt.fairyfox.io.random-ai-prompt-2.60.2.tar.gz-- source tarball (run with Node 24:npm installthennpm start).random-ai-prompt-2.60.2-docs.zip-- the generated documentation site.
What's Changed
- Docs: adopt six mesh standards + coins on the docs chrome by @1fairyfox in #55
- Adopt hub 0.20.2 -> 1.6.1 standards span by @1fairyfox in #58
- Release v2.60.2 by @1fairyfox in #61
Full Changelog: v2.60.1...v2.60.2
v2.60.1
Random AI prompt + image generator for the Stable Diffusion WebUI -- a CLI and a local web UI.
Pre-release software. Provided as-is under Apache-2.0.
What's new in this release
2026-07-13 — 2.60.1 — Security: the backend could be made to run arbitrary commands
CodeQL flagged it on the release PR and it was right. /api/image/open and /api/image/reveal built a
shell string around a request-derived path:
exec(`cmd /c start "" "${fp}"`);
exec(`explorer /select,"${fp}"`);resolveOutputFile() blocks path traversal and nothing else, so an image in the output folder named
x" & calc & ".png closes the quote and everything after it runs. The ImageMagick convert/resize calls
had the same shape. Severity: critical (js/command-line-injection).
The fix is structural, not a better escape function — escaping is a losing game played on the attacker's
board. No shell: the program and its arguments are built separately (new
targets/web/backend/osCommands.js, pure and testable) and handed to execFile, which passes argv
straight to the OS. A quote inside a filename is then just a quote inside a filename. detectMagick
lost its shell too — nothing there needed one.
Three more from the same sweep, all real:
- Prototype pollution (
js/remote-property-injection, high):mergeSidecarmerged a
request-supplied patch key-by-key into a plain object, so{"__proto__": {…}}mutated
Object.prototypefor the whole process. Those keys are now dropped. - World-writable temp cache (
js/insecure-temporary-file, high): the remote manifest was cached at a
fully predictable path inos.tmpdir(), where any local account could pre-create or symlink it — and
we'd write through it and then trust what we read back. Moved into the app's own directory, mode 0600. - Check-then-use races (
js/file-system-race, high ×3):existsSync+ read/write/unlink. Replaced
with do-it-and-handle-ENOENT/EEXIST — the check was always a lie about the future anyway.
Regression-tested (tests/regression/commandInjection.test.js, 5), and the test was proven by
restoring the oldcmd /c startshape and watching it go red.
"It's a local-only backend" is mitigation, not absolution: it is one--hostflag from a LAN.
How to get it
Prefer not to build? Download a pre-built edition:
- Desktop app -- Windows
.msi/.exe(or a portable.zip), macOS.dmg, Linux.AppImage/.deb(attached below). Self-contained; nothing to install first. random-ai-prompt-2.60.1-online.zip-- the online edition as static files; host it anywhere, or just use https://prompt.fairyfox.io.random-ai-prompt-2.60.1.tar.gz-- source tarball (run with Node 24:npm installthennpm start).random-ai-prompt-2.60.1-docs.zip-- the generated documentation site.
What's Changed
- Release v2.60.1 - security by @1fairyfox in #52
Full Changelog: v2.60.0...v2.60.1
v2.60.0
Random AI prompt + image generator for the Stable Diffusion WebUI -- a CLI and a local web UI.
Pre-release software. Provided as-is under Apache-2.0.
What's new in this release
2026-07-12 — 2.60.0 — The verdict: 1000 prompts render in 253 ms on a phone, with flat memory
The number the whole exercise existed to produce, from the release APK on a real Android runtime:
| Roll | engine | render | memory | jank |
|---|---|---|---|---|
| 20 | 1497 ms | 383 ms | 112 MB | 95.7% |
| 200 | 5447 ms | 196 ms | 122 MB | 92.7% |
| 1000 | 23366 ms | 253 ms | 110 MB | 89.8% |
| The list virtualizes exactly as promised: 50× the rows costs no more memory (110 MB vs 112 MB) and | ||||
| no more render time (253 ms vs 383 ms), and the cost per prompt falls with N (94 → 28 → 24 ms). The | ||||
| jank is the emulator's software GPU — identical across all three rolls, which is precisely why the gate | ||||
| judges each roll against the same device's own baseline rather than an absolute frame budget. |
2026-07-12 — 2.60.0 — …and the "defect" it first reported was my test
The on-device gate's first runs said the app missed its headline promise: 1000 prompts, no
"1000 generated" inside ten minutes. For a few hours the notes said so. It was wrong, and what
proved it was the instrumentation added to diagnose it:
[rap-perf] roll 1000 prompts: 13044ms (engine only)
[rap-perf] committed 1220 result rows ← 34 ms later
The engine produced all 1000 prompts — 13.0 s on a software-rendered CI emulator, linear across 20 → 200
→ 1000 — and React committed every row 34 ms later. Nothing was slow.
The bug was in the test: results accumulate across rolls (each batch is prepended, by design), so
after the 20-prompt baseline the label reads "220 generated", and a test waiting for "200 generated"
waits forever. It then burned a ten-minute timeout per roll and reported that as the app failing. The
suite now clears the list before each roll (new clear-all testID).
Two lessons, both now in the notes:
- The test's verdict was louder than the app's evidence, and I believed the test. The
[rap-perf]
lines were sitting in the log the whole time. Read the instrument you built before you distrust the
thing it measures. - It retires the 2026-07-11 conclusion that FlashList's web renderer was to blame for the same
symptom in the proxy.scripts/probe-mobile-list.mjs: the export renders 1000 prompts in 165 ms with
16 rows mounted in the DOM. That explanation was comfortable and false.
2026-07-12 — 2.60.0 — CI gets two tiers: fast on every push, expensive on the release path
Owner: "only use CI for things that don't take a lot of time; things that take a lot of time should be
gated for release/ship/deploy only."
The android-device job compiles the Android app from source and boots an emulator — 30–45 minutes. Run
on every push to dev, it made each one-line iteration a 40-minute wait (and, this session, several of
them). It now runs where it actually protects something: the pull request into main, pushes to
main, and workflow_dispatch. main still cannot take a build it rejects — the release PR must be
green — while dev stays fast. A gate that makes iteration miserable is a gate people learn to ignore.
2026-07-12 — 2.60.0 — The harness itself (Detox on a real Android runtime)
The mobile testing mandate had one honest exception, and this closes it. The app promises 1000
prompts in a single roll with no performance loss — a claim about a phone. The react-native-web
proxy could never check it: it runs FlashList's web renderer, which doesn't recycle like the native
one, so any number it produces describes react-native-web. The test was kept skipped, with the
measurements inline, rather than deleted (pretending) or left failing (crying wolf).
Now there's a real harness: targets/mobile/e2e/ + .detoxrc.js — Detox driving the release APK
(built from the Expo-CNG native project, which stays gitignored) on an emulator; local via the
rap_phone AVD, in CI via a new android-device job (KVM-accelerated Ubuntu runner).
What it asserts, and why it can't be gamed. Not "1000 prompts in under N ms" — that benchmarks
whatever box CI got. It rolls 20, then 1000, on the same device in the same session, and
compares: a virtualized list holds a window of rows, so 50× the data must not mean 50× the memory or a
collapsed frame rate. The evidence is the platform's own accounting — dumpsys gfxinfo (janky-frame
%, p50/p90/p95/p99) and dumpsys meminfo (real PSS) — not a stopwatch inside the test. Emulator noise
is identical in both rolls and cancels. It also pins that the app produced all 1000 (the wait is on
the literal "1000 generated", so a re-introduced cap times out rather than passing quietly) and that
the app is still interactive afterwards.
Also: gradle/ndk-override.init.gradle — an opt-in escape hatch (ANDROID_NDK_VERSION) so a local
build uses an NDK you already have instead of stalling for hours on a 700 MB download of the exact
pinned one. No-op in CI.
2026-07-12 — 2.60.0 — De-dup, the last one: engine/dplInsertCatalog.js
The DPL insert catalog describes what engine/core/dpl/dpl.js compiles — the constructs, their
syntax, their templates. That is the engine's grammar; it was never the web target's to own, and the
phone's 262-line hand-port existed only because the web owned it (guarded by checkDplInserts).
The plan called this one "entangled", because the web localizes the menu's labels through react-intl
while mobile inlines English — sharing the module naively would have dragged react-intl into React
Native. The split that resolves it generalizes: grammar is shared, presentation is not. The engine
holds ids / syntax / templates / examples / materializeTemplate; each target attaches its own label
layer via buildInsertMenu({category, item}). Label keys are derived from the catalog ids, so a
construct added to the grammar with no string in a target fails tests/unit/dplInsertCatalog.test.js
instead of rendering undefined on a phone.
Mobile 262 → a label table; web 264 → 24. checkDplInserts deleted — six of the seven drift checks
are now gone, each because the thing it guarded can no longer differ.
2026-07-12 — 2.59.1 — The local gate was a SUBSET of the CI gate (CI had been red, unseen)
gh run list on dev: CI failing since the previous session's last push — on Format check.
Nine files that session wrote were never Prettier'd, and npm test ran lint but not format:check,
which CI does. So the session ended "green" on a commit CI rejects. A gate you don't run is not a gate
— and a local gate that is a subset of the CI gate is a lie about what green means. format:check now
runs inside npm test.
Two of the nine were generated files, and that exposed a deadlock: hand-formatting them made
check:registry call them STALE (it compares byte-for-byte against the generator's output), while
leaving them made format:check red — two gates each demanding the other be broken. Fixed at the
source: scripts/build-provider-registry.mjs runs its rendered output through Prettier before writing
and before comparing. Never hand-format a generated file.
2026-07-12 — docs — The notes are the system of record (working-agreements §A0)
Owner: "look in the notes please — use them by default and grow accustomed to them by default."
Written down as a hard rule, in both places an assistant actually reads: CLAUDE.md's Start Here
is now an ordered session-start ritual (status.md → the latest session log → the plans//systems/
page for the area being touched), and working-agreements.md gains §A0 — notes read first, used as
the default source of truth over any private/AI memory, written back in the same change. Also refreshed
the CLAUDE.md notes index (it still said "there is no automated suite yet").
2026-07-12 — 2.59.0 — De-dup: the building-block catalog → engine/blockCatalog.js
The token cloud + the DPL autocomplete are engine domain: they describe the engine's own content
pools, their folder categories, the virtual {#any} / {keyword} wildcards, the NSFW gate, and the
naming rules. Nothing about that is a UI concern — the UI just renders what it returns. And it's a pure
function of a loader, which is precisely why it could be shared: each target passes its own
(runtimeLoader in the browser, metroLoader on the phone).
targets/web/frontend/lib/promptEngine.js: 411 → 219 lines.targets/mobile/lib/blockCatalog.js: 218 → 33 lines (a hand-port with no drift check at all —
the worst case, because nothing would have noticed the phone's palette falling behind the web's).
Replaced with a real test (tests/unit/blockCatalog.test.js, 9): the catalog's rules ({#any}leads,
{salt}trails,{keyword}exists, NSFW hidden by default and additive when adult is on,
expansion/never listed), the completion flattening, and — the one a hand-port could never give you —
that the phone never invents content the engine doesn't have.
Two things that test taught me, both worth keeping:- I first asserted a byte-identical catalog across the two loaders. It failed on
{#beach-merk}, and my
instinct was "mobile is missing a block". It wasn't: that's the repo-rootuser/overlay, a
desktop-only content pool (the phone's user content is its on-device Manage overlay). The test
was wrong, not the app — so I asserted the real invariant rather than weakening it until it passed. - The comparison then failed intermittently because
metroLoadercarries a module-level runtime overlay
and a sibling suite left one installed. Reset it inbeforeAll; run the suite twice to prove it's
order-stable.
Also: 43 coverage artifacts had been committed in 2.58.0 (targets/mobile/coverage/wasn't
gitignored, tho...
v2.52.0
Random AI prompt + image generator for the Stable Diffusion WebUI -- a CLI and a local web UI.
Pre-release software. Provided as-is under Apache-2.0.
What's new in this release
2026-07-10 — Address CodeRabbit review across the mobile target (2.52.0)
Worked through the mobile-app review findings so the 2.52.0 PR's conversations resolve on merit:
- Stability/timeouts: a shared
fetchWithTimeout(AbortController + 120s, merges any caller signal)
now backs every network call inlib/imageProviders.js;lib/storage.jsraces remotedownloadAsync
against a 60s timeout so a stalledhttps:source can't hangsaveImageSrc;lib/keys.jssetKey
returns a success flag and the BYOK key field warns on a failed keystore write instead of looking
saved. - Error handling: GalleryScreen surfaces a load failure with a Retry (no more infinite "loading…")
and wrapsdeleteSelected; SingleScreendoConvertgained thebusyguard + serialization its
doResize/doUpscalesiblings already use. - Correctness: GenerateScreen insert-menu / block-palette tokens now target the active field
(Prompt or Negative), and result-row ids use a monotonic per-click batch counter so a fixed
promptSeedcan't collide ids and misattribute images across rows; the "Rewriting…" status always
clears on the copy/no-provider path. - Polish: ComfyUI
batch_sizefloor-clamped to ≥1 (parity with the WebUI path); custom list names
disallow/(they wouldn't round-trip in the flat lists dir);index.jsuses an explicit./App.js
import extension.
2026-07-10 — CodeRabbit review: harden mobile-parity tooling + metroLoader test
Addressed the CodeRabbit review items on the release-hardening code itself. The visual-parity dev server
now guards decodeURIComponent (a malformed escape like /% no longer crashes it before the fs try
blocks); build-metro-catalog.mjs derives generated .js import specifiers from the OUTPUT file's
directory (so a custom --out resolves correctly) instead of a hardcoded ../data/blocks/; and
tests/mobile/metroLoader.test.js tightened its known-value assertions (toBeTruthy + explicit
object-or-null / never-undefined checks) so a loader regression returning undefined can't slip past
not.toBeNull() / not.toThrow().
2026-07-10 — Release-harden 2.52.0: use the CodeQL-recommended path-traversal sanitizer
Follow-up to the traversal fix: containment guards (ternary, then early-return startsWith) were both
logically correct but CodeQL's taint tracker still saw req.url-derived data reach statSync/
readFileSync and kept the 3 high js/path-injection alerts. Switched to the exact sanitizer form the
js/path-injection help recommends — normalize() the request, strip any leading ../ / ..\
segments, then join under OUT — which CodeQL recognizes as sanitizing. Verified every traversal
variant (raw, ..%2f, %2e%2e, interior ../) stays inside the served directory; normal assets
resolve unchanged.
2026-07-10 — Release-harden 2.52.0: remove mobile dead code + align test assertions
Cleared the CodeQL "unused" notes and SonarCloud Reliability/Maintainability findings that blocked the
2.52.0 release PR — real cleanup, no gate-silencing. Removed 8 unused imports/variables in the mobile
target (App.test.jsx top-level Text, BlockPalette.test.jsx an unused getByText destructure,
GenerateScreen.test.jsx waitFor, lib/icons.js G, GenerateScreen.js ShuffleIcon,
SingleScreen.js TextInput + promptText imports + the upscaleProvider theme destructure). In
tests/mobile/single.test.js, aligned the three numeric detail assertions (Steps/CFG/Seed) with the
string-valued Object.fromEntries map Sonar infers, and switched toBe(null)/.length).toBe() to the
dedicated toBeNull/toHaveLength matchers.
2026-07-10 — Release-harden 2.52.0: earn metroLoader Node coverage (race-free)
Reverted the engine/core/metroLoader.js coverage exclusion (silencing a real gap) and instead EARNED
its coverage with tests/mobile/metroLoader.test.js — exercises every accessor and proves the loader
drives createEngine byte-identically to nodeLoader; metroLoader.js is now measured (~87%) rather
than hidden. Only the generated, gitignored engine/core/metroCatalogData.js stays excluded (data, not
logic), and it's now also excluded from Sonar analysis/coverage/duplication so the CI-built blob isn't
scanned. Made the parity check deterministic by moving the catalog build + a clean-state snapshot of
nodeLoader's names and parity generations into a Vitest globalSetup
(tests/setup/metro-catalog.globalSetup.js), captured before any worker spawns — so it can no longer
race manageFs.test.js's transient shared-FS fixtures or a concurrent-read scan miss on Windows.
2026-07-10 — Release-harden 2.52.0: fix path traversal in the mobile visual-parity server
CodeQL flagged three high-severity "uncontrolled data in a path expression" alerts in the mobile
visual-parity dev server (scripts/mobile-visual-parity.mjs): req.url flowed straight into
join(OUT, …) → statSync/readFileSync with no boundary check, so GET /../../etc/passwd could
escape the served directory. The server now resolves each request under an absolute OUT_ROOT and
rejects anything that leaves it (falling back to index.html), blocking raw and URL-encoded
(..%2f, %2e%2e) traversal while normal asset paths resolve unchanged.
2026-07-10 — Mobile: full Single-view parity + first automated test layer (2.52.0)
MINOR milestone. Rounds out the mobile (Android/Expo) target to web parity on the Single view and
stands up its first automated tests. See the detailed entries below; in brief: SingleScreen rebuilt to
full parity with the web SingleView (nav, layered prompt/negative, inline re-roll/variation, convert/
resize/upscale, lineage + derived strips, details/raw-JSON/copy, keyword cloud), the Generate/Gallery
parity gaps closed, and a jest-expo + React Native Testing Library suite (64 tests) covering every
mobile screen, menu, and lib module — wired into npm test (test:mobile). targets/mobile excluded
from the root ESLint + Prettier (Expo owns its own toolchain), matching targets/web.
2026-07-10 - Mobile: component tests for every screen/menu + lib unit tests
Completed the mobile automated test layer to the web suite's "every module covered" bar. 64
mobile-specific tests, all green:
- Component (jest-expo + RNTL, 40 across 10 suites): App shell (tabs + ⋯ overflow), SingleScreen,
GenerateScreen, GalleryScreen, ManageScreen, OverflowMenu (three-role picker / appearance / language
over the real registry), InsertMenu (DPL construct drill-in + insert), BlockPalette (search + groups +
chip insert), plus lib keys (secure-store) and storage (file-system index). - Unit (root vitest, 24 across 2 files): lib/single.js (16) and lib/imageProviders.js registry /
defaults / systemFor / structural invariants (8). - Added
accessibilityLabels to the remaining icon-only buttons (App ⋯) — a11y parity + test handles.
jest.setup mocks safe-area (useSafeAreaInsets), status-bar, and FlashList (header + rows + empty).
2026-07-10 - Mobile: component tests extended to Generate / Gallery / Manage
Grew the jest-expo + RNTL suite from Single to every screen (20 tests, all green): GenerateScreen
(composer renders, rolling fills the results feed, the gear opens the full settings sheet, live
preview), GalleryScreen (header/count/search/select/refresh/composer, search filter, multi-select,
empty state), ManageScreen (lists master view, create-opens-editor, open windowed editor, delete,
empty state). Added accessibilityLabels to the icon-only buttons exercised (Generate, Prompt
settings, Toggle live preview, Generate-here) — an a11y-parity gain with the web's aria-labels as well
as test handles. The shared FlashList test mock now renders ListEmptyComponent, and the safe-area
mock exports useSafeAreaInsets.
2026-07-10 - Mobile: jest-expo + RNTL test harness; component + helper tests
Stood up the mobile target's first automated test layer (it had none) to the bar of the web suite —
real component tests that mount the actual RN screens (the Android code path) through the jest-expo
renderer with native modules mocked:
- Harness:
jest-expopreset +@testing-library/react-native+ pinnedreact-test-renderer
(19.1.0, matching React 19.1.0);jest.setup.jsmocks the native leaves (expo-image, FlashList,
expo-file-system/legacy, expo-image-manipulator, expo-media-library, expo-sharing, expo-clipboard,
expo-secure-store, safe-area-context). Run vianpm --prefix targets/mobile test, wired into root
npm testastest:mobile. - Single component tests (
screens/__tests__/SingleScreen.test.jsx, 7): mounts the real screen and
asserts nav/position/tools render, the layered Prompt+Negative cards render from metadata, the details
table renders, the keyword cloud fires search, inline Re-roll fires the provider's generate adapter,
Back invokes its callback, and the empty state shows. - Single helper unit tests (
tests/mobile/single.test.js, 16, root vitest): layer normalization
(enriched + legacy), buildDetails, parseKeywords, linkChildren, sizeFromSettings, toMarkdown,
searchHaystack. - Excluded
targets/mobile/**from the root ESLint (Expo has its own toolchain), matchingtargets/web/**.
2026-07-10 - Mobile: Single view rebuilt to full web parity; Generate/Gallery gaps closed
Comprehensive web-to-mobile comparison of the remaining surfaces (SingleView.jsx + its subcomponents,
PromptComposer, Gallery), then brought the mobile app to parity:
- Single (
screens/SingleScreen.js, rebuilt): prev/next nav + position, open-full viewer, share
(expo-sharing) / save-to-Photos (expo-media-library) / delete overlay actions, Convert (format) +
Resize (scales) + AI Upscale via expo-image-manipulator, lineage header + par...
v2.51.1
Random AI prompt + image generator for the Stable Diffusion WebUI -- a CLI and a local web UI.
Pre-release software. Provided as-is under Apache-2.0.
What's new in this release
2026-07-09 — Fix the DPL editor's white gutter + washed-out active line in dark mode (2.51.1)
The live editor showed a bright-white line-number column and a milky blue active-line band in dark
mode. Root cause: CodeMirror 6's gutter baseTheme ships both &light .cm-gutters {#f5f5f5} and a
&dark variant, chosen by whether the view's theme declares { dark: true } — and our editors never
did. So CM stayed in light mode and injected the light gutter (#f5f5f5), the light active-line
gutter (#e2f2ff), and the milky active-line wash (rgba(204,238,255,.267)) at the SAME specificity
as our .dpl-editor .cm-* CSS, beating it on source order. A plain-CSS override could never win.
- New shared
themeextension (targets/web/frontend/lib/editorChrome.js): a CodeMirror
EditorView.theme(StyleModule priority > baseTheme, so it wins) that sets a transparent gutter
with dim recessed numbers, a brighter neutral active-line NUMBER, a whisper-subtle neutral
active-line lift (4.5% of--fg), and the accent-tinted selection. Colors are the app's CSS
variables, so the chrome tracks light/dark on its own (no hard-pinneddarkflag). - Wired into both editors —
DplEditor.jsx(the prompt boxes) andCodeEditor.jsx(Manage's
code/list editors, which had NO gutter override and showed the same white slab). - Dropped the dead CSS in
dpl-editor.css(the losing.cm-gutters/.cm-activeLine*/selection
rules), leaving a comment that explains why the chrome lives in the theme now. - Regression test
tests/e2e/editor-chrome.spec.js— asserts (dark scheme) a non-light gutter
surface and a neutral, untinted active-line band. Verified visually at prompt.fairyfox.io parity in
dark AND light mode.
How to get it
Prefer not to build? Download a pre-built edition:
- Desktop app -- Windows
.msi/.exe(or a portable.zip), macOS.dmg, Linux.AppImage/.deb(attached below). Self-contained; nothing to install first. random-ai-prompt-2.51.1-online.zip-- the online edition as static files; host it anywhere, or just use https://prompt.fairyfox.io.random-ai-prompt-2.51.1.tar.gz-- source tarball (run with Node 24:npm installthennpm start).random-ai-prompt-2.51.1-docs.zip-- the generated documentation site.
What's Changed
- Release v2.51.1 by @junebug12851 in #48
Full Changelog: v2.51.0...v2.51.1
v2.51.0
Random AI prompt + image generator for the Stable Diffusion WebUI -- a CLI and a local web UI.
Pre-release software. Provided as-is under Apache-2.0.
What's new in this release
2026-07-07 — Pre-release hardening: preset-loader path-traversal fix + engine-module coverage (2.51.0)
SonarCloud (on the 2.51.0 release PR) flagged the new shared engine modules — fixed for real before
shipping rather than merging a red gate:
- Security (path traversal).
engine/presets.jsloadPreset(name)built a file path fromname,
which arrives from the/api/promptrequest body — so a craftedpresetwith../separators could
read arbitrary*.jsonfiles. It now rejects anything but a plain preset name. Regression-tested. - Coverage. The three new modules (
promptRun.js/nodeEngine.js/presets.js) weren't in the
Vitest coverage allowlist, so Sonar saw 0% on them. Added them + focused unit tests
(tests/unit/{promptRun,presets,nodeEngine}.test.js) → ~100% lines each; global thresholds hold. - False positive. Suppressed S2245 (
Math.random) forpromptRun.js's batch-seed mint — a creative
prompt seed, never security-sensitive (same as the existingrng.js/random.jssuppressions).
Full gate green (419 web + the Node suite incl. the new specs).
2026-07-07 — New targets/comfyui/ target: ComfyUI prompt-engine nodes (2.51.0)
Added a ComfyUI custom-node target (targets/comfyui/) that brings the prompt engine into ComfyUI as
natural-language-first STRING sources for a CLIP Text Encode. Prompt-side only — ComfyUI already
owns image generation, upscaling, variations, and re-roll (its native seed widget), so the target adds
just the prompt half (the DPL processor, blocks, lists, presets).
- Thin Python wrappers, no re-ported engine logic. The nodes make HTTP calls to a running app's
local backend (point-at-running-app; defaulthttp://localhost:4173, auto-detects a running app on
localhost:4173/5173, override via a Settings field /RANDOM_AI_PROMPT_URL). Two new backend routes power it —
POST /api/promptandGET /api/prompt/catalog— reusing the sharedengine/promptRun.js,
engine/nodeEngine.js, andengine/presets.js(all extracted this session so nothing is duplicated;
the CLI re-exports the same modules). Dependency-free (stdliburllib). - Nodes: a flagship natural-language
RandomAIPromptGenerator(template + seed + nsfw + preset) plus
helpersPromptList/PromptBlock/DPLExpand/PromptBatch(N variations as a list) /
CombinePrompts(join wired pieces) /ShowPrompt(display + pass-through). Re-roll is the native seed
widget (control_after_generate); presets come fromengine/data/presets(+user/presets). Every
input/output carries a tooltip + each node a description; the generator is top-level, the helpers grouped
under a submenu. (An AI-rewrite node was considered and dropped — calling a third-party API mid-graph is
off-paradigm for ComfyUI, and the plugin now makes zero third-party calls.) - Frontend extension (
web/randomAiPrompt.js): the single Settings URL field (drives dropdowns and
generation via a persisted/random_ai_prompt/config), LIVE dropdowns from the catalog (same-origin
proxy routes, avoiding CORS), the app icon + brand colours on the nodes, theShowPrompttext display,
and a status sidebar. Plus a drag-inexample_workflows/starter and an Apache-2.0LICENSE. - Verify: the engine/backend side is covered by
tests/integration/promptApi.test.js(generate, seed
reproducibility, preset apply + unknown→400, catalog); the Python + ComfyUI-runtime JS are
syntax-checked and must be validated in a running ComfyUI (manual — no CI runtime). Full gate green.
New deep-divesystems/comfyui.md; credits +CLAUDE.mdupdated; legal pages
re-checked (localhost only — no third-party data flow).
2026-07-07 — Dispose of the chaos knob; extract a shared engine-owned prompt-run (2.50.1)
Removed the chaos value for good. It was a pre-DPL knob for controlling randomization (scaling the
whole emphasis/editing/alternating envelope at once, with blocks meant to react to it) that predated the
DPL wrapper and was never liked; it was never an engine setting (engine/settings.js never had it), and
its UI control had already been unmounted on 2026-06-19. Deleted withChaos from the web facade
(targets/web/frontend/lib/promptEngine.js) and the CLI, dropped the CLI --chaos flag
(optionSpec.js), and swept the current-state docs (removed-pending-readd.md row deleted; status.md,
cli.md, dpl-language.md, prompt-dsl.md, next-steps.md, the Home.jsx comment). Left untouched:
Midjourney's own unrelated --chaos provider parameter, and the word "chaos" in the vocabulary lists /
block descriptions. Default prompt output is byte-identical (withChaos was a no-op at chaos = 1); the
snapshot + CLI reproducible-prompt tests confirm it.
In the same pass, extracted the duplicated seed/reroll prompt-run logic into a new engine-owned,
isomorphic module engine/promptRun.js (seedFor, forEngine, and a createPromptRun(engine)
factory). The web SPA facade and the CLI's promptRun.js now consume it instead of each carrying their
own copy — so the seed rules live in one place, and the upcoming ComfyUI backend prompt route can reuse
them rather than re-porting the logic a third time. No behavior change: 293 Node + 419 web tests, lint,
and doc-link checks all green.
2026-07-07 — New targets/cli/ target: the prompt command-line tool (2.50.0)
Added a command-line build target — a traditional args-and-flags CLI (prompt, package
@random-ai-prompt/cli) that generates prompts and runs them through image providers using the same
engine, providers, settings, and on-disk store as the web/desktop app (parity with both the engine
and the GUI, by default). No TUI/interactive mode — every capability is a subcommand with flags, a
--help page, colored output (picocolors; honors NO_COLOR/FORCE_COLOR), and completion for
bash, zsh, fish, and PowerShell.
- Commands:
generate(default; everyengine/settings.jsfield is a flag, plus provider/image/
rewrite knobs,--seed/--random,--nsfw,--preset,--json),list
(blocks/lists/providers/presets/dialects/samplers/settings),config,keys,rewrite,upscale,
andcompletion. - Reuse, not fork: a Node provider registry (
src/lib/providers.js) replaces the SPA's Vite-glob
registry (fs-discoversshared/<id>/config.js+_shared/settings/*.js); the CLI runs the real
backend (apiHandler.js) in-process on an ephemeral port with afetchshim, so every
provider's owncode/generate.jsruns unchanged and images save to the sharedoutput/folder with
the same sidecar the gallery reads. An ESM resolve hook (src/lib/jsonLoader.mjs) injects
type: jsonso the providers' bare JSON imports load under Node. - Shared state: CLI defaults persist to their own
clinamespace (never clobbering the GUI's
settings.json); BYOK keys are read from both stores, so keys are shared between the CLI and the app
(or supplied per-run viaPROMPT_KEY_<PROVIDERID>). Anapiprovider is only called with--images,
so a plainprompt -p openai "x"never spends credits. - Wiring/tests: root
postinstallinstalls the CLI;npm run cliruns it; the root ESLint gate
now lintstargets/cli(Node ESM) and CLI unit tests live intests/cli/cli.test.js(14 tests, in
the root Vitest gate). Seesystems/cli.md.
How to get it
Prefer not to build? Download a pre-built edition:
- Desktop app -- Windows
.msi/.exe(or a portable.zip), macOS.dmg, Linux.AppImage/.deb(attached below). Self-contained; nothing to install first. random-ai-prompt-2.51.0-online.zip-- the online edition as static files; host it anywhere, or just use https://prompt.fairyfox.io.random-ai-prompt-2.51.0.tar.gz-- source tarball (run with Node 24:npm installthennpm start).random-ai-prompt-2.51.0-docs.zip-- the generated documentation site.
What's Changed
- Release v2.51.0 — ComfyUI target + headless prompt routes by @junebug12851 in #47
Full Changelog: v2.49.6...v2.51.0
v2.49.6
Random AI prompt + image generator for the Stable Diffusion WebUI -- a CLI and a local web UI.
Pre-release software. Provided as-is under Apache-2.0.
What's new in this release
2026-07-06 — Tone down the DPL editor's active-line + line-number gutter on dark (2.49.6)
Follow-up to 2.49.5: the active-line highlight was a color-mix(--accent 7%) band that read as a milky,
washed-out mint slab on the dark theme, and the line numbers used full --faint with a bright --accent
active number — both too loud. Reworked to be quiet and neutral: the active-line body is now a
whisper-subtle color-mix(--fg 3.5%) lift (theme-adaptive, no color cast), inactive numbers are dimmed
(--faint at 55% alpha) so they recede, and the active line's number is a clean neutral --muted
brighten instead of the glowing accent. Verified in Chrome on the dark theme (mid-editor active line +
gutter). CSS-only.
How to get it
Prefer not to build? Download a pre-built edition:
- Desktop app -- Windows
.msi/.exe(or a portable.zip), macOS.dmg, Linux.AppImage/.deb(attached below). Self-contained; nothing to install first. random-ai-prompt-2.49.6-online.zip-- the online edition as static files; host it anywhere, or just use https://prompt.fairyfox.io.random-ai-prompt-2.49.6.tar.gz-- source tarball (run with Node 24:npm installthennpm start).random-ai-prompt-2.49.6-docs.zip-- the generated documentation site.
What's Changed
- Release v2.49.6 — quiet DPL editor active-line/gutter on dark by @junebug12851 in #46
Full Changelog: v2.49.5...v2.49.6
v2.49.5
Random AI prompt + image generator for the Stable Diffusion WebUI -- a CLI and a local web UI.
Pre-release software. Provided as-is under Apache-2.0.
What's new in this release
2026-07-06 — Interactive DPL editor layer: hover dials, + line actions, gutter, coloring (2.49.5)
A standardized interactivity layer added to the shared DplEditor (so every prompt box — regular /
negative / gallery / Manage — gets it at once):
- Hover intensity/focus dials. Resting on a
{#…}block reference floats two little speedometer
dials above it (INTENSITY, FOCUS), 50 dead-center / straight-up. Dragging (or double-clicking) writes
iNN%/fNN%back into that one reference; landing on exactly 50 (the default) drops the argument so
the reference stays clean. Newlib/dpl/dplDials.js(a plain CodeMirrorViewPlugin; the panel is
position:fixedondocument.bodyso it never clips, re-anchored on scroll + after each edit). +context-aware line actions. A+sits in a left gutter on the hovered/cursor line; clicking it
opens a menu that adapts to context: inside the---front matter → front-matter keys + blank-line
inserts; the first line with no front matter yet → "Insert front matter"; a line with content →
"Promote to…" (wrap as-/maybe/NN% chance/otherwise/[weight]/[i<NN%]); always →
"Replace line with…" (every line-type template), insert blank line above/below, and "New section…"
(standard Start / Auto Begin / Auto End, or a custom one). Newlib/dpl/dplLineActions.js.- Line numbers + active-line highlight.
lineNumbers()+highlightActiveLine()/
highlightActiveLineGutter(), themed via the--*tokens indpl-editor.css. - Syntax-coloring gaps closed (
dplLanguage.jstokenizer): theinsert js:path now colors as a
ref;otherwise NN%/otherwise maybecolors the whole gate; the(NN% nothing)choice miss is part
of the choice keyword; and a combined[100 i<10% f<40%]weight/condition bracket colors as one dial
unit (was previously mangled). - New localized strings live in
lib/dpl/dplInteractiveMessages.js(formatted throughintland passed
into the plain-CM extensions). Verified in Chrome across all four editors; full headless gate green
(lint incl. stylelint, smoke, 416 web tests incl. the SSR prerender guard, web build).
How to get it
Prefer not to build? Download a pre-built edition:
- Desktop app -- Windows
.msi/.exe(or a portable.zip), macOS.dmg, Linux.AppImage/.deb(attached below). Self-contained; nothing to install first. random-ai-prompt-2.49.5-online.zip-- the online edition as static files; host it anywhere, or just use https://prompt.fairyfox.io.random-ai-prompt-2.49.5.tar.gz-- source tarball (run with Node 24:npm installthennpm start).random-ai-prompt-2.49.5-docs.zip-- the generated documentation site.
What's Changed
- Release v2.49.5 — interactive DPL editor layer by @junebug12851 in #45
Full Changelog: v2.49.4...v2.49.5
v2.49.4
Random AI prompt + image generator for the Stable Diffusion WebUI -- a CLI and a local web UI.
Pre-release software. Provided as-is under Apache-2.0.
What's new in this release
2026-07-06 — Fix Manage add-menu overflowing the pane (2.49.4)
The tree's add (+) menu ("New block / New folder") opened left-to-right (left: 0) from + controls
that sit near the right edge of the narrow tree pane, so the 130px menu spilled past the pane and forced
a horizontal scrollbar. Right-aligned it (right: 0; left: auto) so it grows leftward and stays inside
the pane. Verified in Chrome. CSS-only.
2026-07-06 — "Create override" for built-in blocks/lists + corner scrollbar fix (2.49.3)
- Create override: the block + list editors now show a Create override button for any built-in
entry. It copies the entry (content +.js/.jsonsidecars) into the matching user-overlay root
(user/blocksoruser/lists) — which wins at runtime and survives app updates — then selects the
new copy so you edit YOUR version; the built-in is left untouched. If an override already exists it
just opens it. Backed by a new cross-rootcopyfs op (toRoot) inmanageFs,overrideEntryin
useManageTree, and a confirm dialog. Verified end-to-end in Chrome. - Corner scrollbar fix: the Modify/Draft combo overlapped the DPL editor's vertical scrollbar —
inset it (right: 1.25rem) so it always clears the scrollbar. - Editor-freeze fix: the first attempt used
scrollbar-gutter: stableon the CodeMirror scroller,
which put CM into an infinite measure loop and froze the renderer when a block opened. Dropped it (CM
wraps long lines inside the scrollbar already, so the text stays clear without it). - Verified green: the full gate —
check:docs+ lint (incl. stylelint) +smoke+ Node unit (279,
incl. the new cross-root copy round-trip) + web (416, incl.overrideEntrycases) + the web build;
i18n:extractsynceden.json. Manually confirmed the override flow, the scrollbar clearance, and
the freeze fix in the browser.
2026-07-06 — Refine bar UX overhaul: stepper combos + corner Modify/Draft (2.49.2)
Rebuilt the block refine controls after they read as "a slab of buttons overflowing with even more
buttons oddly below it" (verified in Chrome this time — the fix is UX-driven).
- Stepper combos: each dimension is now ONE compact control —
[ − Detail + ]— instead of two
separate "Add detail" / "Trim detail" pills. Five combos (Detail, Complexity, Focus, Intensity,
Variety) + a lone Cleanup pill (renamed from "Tighten") sit on one tidy, wrap-safe row. New
DplRefineBarrenders−/+step buttons per dimension; the +/− aria-labels carry the old action
names. - Corner Modify/Draft: the free-text box moved out of a full-width slab into a joined Modify /
Draft combo pinned to the DPL editor's top-right corner (newDplAskCorner.jsx), opening a compact
popover (title + textarea + Send, ⌘/Ctrl+Enter). The editor content gets a top gutter so the first
line clears the control; the popover caps atmin(88vw, 360px). - Test-infra fix: the heavier suite tipped
promptEngine.integration'sensureCatalog()warmup
hook (~9.3s on HEAD) past the default 10s hook timeout under parallel load — gave thatbeforeAlla
30s timeout (the real data-corpus glob genuinely takes >10s under load). - Verified green: inspected in Chrome at desktop (combos tidy, corner popover clean, no clipping) +
lint +smoke+ the full web suite (412 tests) + the web build;i18n:extractsynceden.json.
2026-07-06 — Free-text "Modify" box for block refine in Manage (2.49.1)
Added a free-text message box to the block editor's refine bar so a template can be re-processed by a
typed instruction — full control alongside the quick pills. A segmented Modify / Draft new toggle
sits over one input: Modify (default) sends your instruction plus the current template to the AI and
applies the revised DPL; Draft new is the previous draft-from-description (now folded into the same
box). Both keep the existing validate + dirty-until-Save + one-click Undo behaviour.
- New
dpl-custommode (rewriteSystem.js): its task tells the model the user message is an
INSTRUCTIONfollowed by the current template after a--- TEMPLATE ---delimiter, to apply the
change and return the full revised DPL while preserving everything not asked to change. Rides on the
sameDPL_PRIMERas the otherdpl-*modes. dplRefine.js:DPL_CUSTOM_MODE+buildCustomPrompt(instruction, template)(packs the two
around the delimiter).DplRefineBar.jsxreplaced the collapsible draft control with the always-
visible Modify/Draft box;ManageBlockEditor.jsxgainedhandleCustom(validates both an
instruction and a template exist, composes the prompt, runsdpl-custom) and akind-driven status.- Verified green: lint +
smoke+ the full web suite (409 tests) + the web build;i18n:extract
synceden.json. No data-practice change, so the legal docs are untouched.
2026-07-06 — AI refine + draft-from-description for blocks in Manage (2.49.0)
Extended the Manage block editor's DPL tab with an AI refine toolbar and a draft-from-description
control, so a block template can be shaped by clicking instead of hand-editing DPL. All of it rides on
the existing text (rewrite) provider path — the same BYOK plumbing the list editor's "AI Expand" uses —
so no new provider code was needed.
- Refine toolbar (
DplRefineBar.jsx): five dimensions as more/less pill pairs — Detail
(add/trim), Complexity (more/simplify), Focus (sharpen/loosen), Intensity (crank/ease),
Variety (more/consistent) — plus a Tighten polish action. Each pill sends the current template
through the provider with a dedicateddpl-*mode and replaces the editor content; the result is
validated (issue count surfaced in the status), marked dirty (not saved until Save), and reversible via
an Undo link (a manual edit supersedes the revert point). - Draft from description: a free-text box drafts a whole starting template from a plain-English
subject, using a "winning formula" system prompt (front matter →Start→ subject spine → essential
bullets →one of:variety →maybe/NN%garnish →[f<40%]focus fluff →[i>70%]/[i<25%]
intensity variants, composable, ~10–20 lines). - DPL-aware system prompts (
rewriteSystem.js): a sharedDPL_PRIMERteaches the model the DPL
grammar and the intensity/focus dials so it refines as DPL (tokens, sections, gates, choices
preserved) rather than flattening to prose;systemFor()now routes everydpl-*mode (primer + a
per-mode task) alongside the existingkeyword/expand/fix. Reused by both transports
(browser-direct + the/api/rewriteproxy) since both already callsystemFor. - New:
frontend/lib/dpl/dplRefine.js(action catalog +cleanDplOutputfence/quote stripper) and
dplRefineMessages.js;styles/components/dpl-refine-toolbar.css. No data-practice change (refine
reuses the already-disclosed text-provider flow), so the legal docs are untouched. - Verified green: lint +
smoke+ the full web suite (404 tests, incl. newdplRefine,
rewriteSystem, andDplRefineBarspecs) + the web build;i18n:extractsynceden.json.
How to get it
Prefer not to build? Download a pre-built edition:
- Desktop app -- Windows
.msi/.exe(or a portable.zip), macOS.dmg, Linux.AppImage/.deb(attached below). Self-contained; nothing to install first. random-ai-prompt-2.49.4-online.zip-- the online edition as static files; host it anywhere, or just use https://prompt.fairyfox.io.random-ai-prompt-2.49.4.tar.gz-- source tarball (run with Node 24:npm installthennpm start).random-ai-prompt-2.49.4-docs.zip-- the generated documentation site.
What's Changed
- Release v2.49.4 by @junebug12851 in #44
Full Changelog: v2.48.0...v2.49.4