check:one-palette sees a bundle's private src/colors/ palettes; Rudder's offline hint states Go 1.22+ and the setup
Two findings from upg100's census. check-one-palette read strategy palettes from library/colors/ only, so a bundle's own src/colors/ strategy (which overrides the library one for that bundle) was never checked; it now reads both, the bundle's over the library's, and --self-test plants a private palette. Rudder's engine-offline notice gave a go build line without saying Go 1.22+ is needed or that setup-runtime.sh downloads the model; it now says both and points at bun run desktop:build and the desktop HOWTO.
This commit is contained in:
parent
4ce8604d42
commit
35955a4db6
2 changed files with 36 additions and 12 deletions
|
|
@ -47,8 +47,9 @@
|
|||
* NEGATIVE-TESTED: reintroducing a private `const CATEGORICAL = ['#...']` into the aggregations
|
||||
* composable fails assertion 2 by name; an `[i % CATEGORICAL.length]` lookup fails assertion 3.
|
||||
*/
|
||||
import { readFileSync, existsSync, readdirSync } from 'node:fs'
|
||||
import { readFileSync, existsSync, readdirSync, mkdtempSync, writeFileSync, rmSync } from 'node:fs'
|
||||
import { resolve, dirname, join } from 'node:path'
|
||||
import { tmpdir } from 'node:os'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import { TREE_NAME } from './_tree-name.mjs'
|
||||
|
||||
|
|
@ -96,7 +97,32 @@ export function paletteHexes(src) {
|
|||
return [...new Set(strings.flatMap((t) => [...t.matchAll(/#[0-9a-fA-F]{6}\b/g)].map((m) => m[0].toLowerCase())))]
|
||||
}
|
||||
|
||||
/**
|
||||
* The strategy palettes in one colors folder: library/colors/, or a bundle's own
|
||||
* plugin-designs/<bundle>/src/colors/ (bundle-private strategies merge OVER the library set for that
|
||||
* bundle — see that folder's README). Filename → key as the registry names it is not needed here; the
|
||||
* file stem is the key both places use.
|
||||
*/
|
||||
export function collectStrategies(dir) {
|
||||
const out = {}
|
||||
if (!existsSync(dir)) return out
|
||||
for (const f of readdirSync(dir)) {
|
||||
if (!f.endsWith('.js') || f.startsWith('_') || f.startsWith('.') || f === 'index.js') continue
|
||||
const hexes = paletteHexes(readFileSync(join(dir, f), 'utf8'))
|
||||
if (hexes && hexes.length) out[f.replace(/\.js$/, '')] = hexes
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
if (process.argv.includes('--self-test')) {
|
||||
// A bundle's PRIVATE palette (src/colors/<mode>.js) must be seen, not only library/colors/ (the gate was
|
||||
// blind to it: upg100's census, BUG-CHECK-ONE-PALETTE-BLIND-TO-PRIVATE-PALETTES).
|
||||
const tmp = mkdtempSync(join(tmpdir(), 'one-palette-'))
|
||||
writeFileSync(join(tmp, 'religion.js'), "export const PALETTE = { islam: '#010203', hinduism: '#040506' }\n")
|
||||
writeFileSync(join(tmp, '_skip.js'), "export const PALETTE = { x: '#999999' }\n")
|
||||
const seen = JSON.stringify(collectStrategies(tmp))
|
||||
rmSync(tmp, { recursive: true, force: true })
|
||||
if (seen !== JSON.stringify({ religion: ['#010203', '#040506'] })) { console.error(`ONE-PALETTE: SELF-TEST FAIL — a planted private palette read as ${seen}`); process.exit(1) }
|
||||
const src = [
|
||||
"export const PALETTE = {",
|
||||
" a: '#112233', // not #445566 (a comment inside the export)",
|
||||
|
|
@ -107,18 +133,14 @@ if (process.argv.includes('--self-test')) {
|
|||
].join('\n')
|
||||
const got = paletteHexes(src).join(',')
|
||||
if (got !== '#112233,#aabbcc') { console.error(`ONE-PALETTE: SELF-TEST FAIL — read ${got}, want #112233,#aabbcc`); process.exit(1) }
|
||||
console.log('ONE-PALETTE: SELF-TEST PASS — only the PALETTE export\'s string values are read; comments and later code are not.')
|
||||
console.log('ONE-PALETTE: SELF-TEST PASS — only the PALETTE export\'s string values are read; comments and later code are not; a bundle\'s private src/colors/ palette is seen.')
|
||||
process.exit(0)
|
||||
}
|
||||
|
||||
// ── the expected palettes, read from the strategy modules the MAP uses ────────────────────────
|
||||
const strategies = {}
|
||||
for (const f of readdirSync(COLORS)) {
|
||||
if (!f.endsWith('.js') || f.startsWith('_') || f.startsWith('.')) continue
|
||||
const src = readFileSync(join(COLORS, f), 'utf8')
|
||||
const hexes = paletteHexes(src)
|
||||
if (hexes && hexes.length) strategies[f.replace(/\.js$/, '')] = hexes
|
||||
}
|
||||
// The library set, and per bundle its own src/colors/ strategies merged over it (same key overrides).
|
||||
const strategies = collectStrategies(COLORS)
|
||||
const privateOf = (bundle) => collectStrategies(join(ROOT, 'plugin-designs', bundle, 'src', 'colors'))
|
||||
|
||||
// ── the consumers that must agree ─────────────────────────────────────────────────────────────
|
||||
const CONSUMERS = [
|
||||
|
|
@ -142,7 +164,7 @@ for (const c of CONSUMERS) {
|
|||
const p = join(BUILT, c.bundle)
|
||||
if (!existsSync(p)) { errs.push(`bundle missing: ${c.bundle} — build is incomplete, so this gate cannot judge it.`); continue }
|
||||
const js = readFileSync(p, 'utf8').toLowerCase()
|
||||
for (const [strat, hexes] of Object.entries(strategies)) {
|
||||
for (const [strat, hexes] of Object.entries({ ...strategies, ...privateOf(c.name) })) {
|
||||
const missing = hexes.filter((h) => !js.includes(h))
|
||||
checkedPairs++
|
||||
// A consumer need not use EVERY strategy, but if it uses one at all it must use the whole
|
||||
|
|
|
|||
|
|
@ -707,8 +707,10 @@ const statusText = computed(() => ({
|
|||
the engine runs on. Open the Plugin Studio on your computer (<code>bun run dev</code>) or use the Rudder desktop app.
|
||||
</p>
|
||||
<p v-else-if="engine === 'offline'" class="notice" data-kind="warn">
|
||||
The local speech engine isn't reachable at <code>{{ apiBase }}</code>. In the Plugin Studio it starts with
|
||||
<code>bun run dev</code> once built: <code>cd backend/rudder-engine && go build -o ../bin/rudder-engine .</code>
|
||||
The local speech engine isn't reachable at <code>{{ apiBase }}</code>. It needs <b>Go 1.22 or newer</b> and a
|
||||
one-time setup that downloads the speech model (about 750 MB): <code>bash backend/rudder-engine/setup-runtime.sh</code>.
|
||||
Then <code>bun run dev</code> starts it here. For the desktop app, <code>bun run desktop:build rudder-voice</code>;
|
||||
both are described in <code>documentation/HOWTO-build-the-desktop-app.md</code>.
|
||||
</p>
|
||||
|
||||
<section class="compose">
|
||||
|
|
|
|||
Loading…
Reference in a new issue