fix: present Cuprate as one launchable app
Demo images / Build & push demo images (push) Successful in 3m28s

This commit is contained in:
archipelago
2026-09-13 03:06:22 -04:00
parent 06bf359535
commit 8c37ff412c
3 changed files with 13 additions and 8 deletions
@@ -78,12 +78,11 @@ describe('appsConfig service filtering', () => {
it('shows Cuprate as one My Apps entry while hiding its daemon dependency', () => { it('shows Cuprate as one My Apps entry while hiding its daemon dependency', () => {
const entries: Array<[string, PackageDataEntry]> = [ const entries: Array<[string, PackageDataEntry]> = [
['cuprate-ui', makePkg('cuprate-ui', 'Cuprate UI', 'money')], ['cuprate', makePkg('cuprate', 'Cuprate', 'money')],
['cuprate', makePkg('cuprate', 'Cuprate daemon', 'money')], ['archy-cuprate-ui', makePkg('archy-cuprate-ui', 'Cuprate UI companion', 'money')],
] ]
;(entries[0]![1].manifest as unknown as Record<string, unknown>).interfaces = { main: { ui: 'http://localhost:18091' } } expect(filterEntriesForTab(entries, 'apps', 'all').map(([id]) => id)).toEqual(['cuprate'])
expect(filterEntriesForTab(entries, 'apps', 'all').map(([id]) => id)).toEqual(['cuprate-ui']) expect(filterEntriesForTab(entries, 'services', 'all').map(([id]) => id)).toEqual([])
expect(filterEntriesForTab(entries, 'services', 'all').map(([id]) => id)).toEqual(['cuprate'])
}) })
it('falls back to packaged app icon when static icon token is not a path', () => { it('falls back to packaged app icon when static icon token is not a path', () => {
+5 -1
View File
@@ -20,6 +20,10 @@ export const isServiceContainer = sharedIsServiceContainer
const INTERNAL_TOOLING_NAMES = new Set([ const INTERNAL_TOOLING_NAMES = new Set([
'buildx_buildkit_default', 'buildx_buildkit_default',
// Cuprate's dashboard is bundled as a companion of the primary cuprate
// package; showing the generated container as a second Services entry
// defeats the one-app presentation.
'archy-cuprate-ui',
]) ])
export function isInternalToolingPackage(id: string, pkg?: PackageDataEntry): boolean { export function isInternalToolingPackage(id: string, pkg?: PackageDataEntry): boolean {
@@ -37,7 +41,7 @@ export function isServicePackage(id: string, pkg?: PackageDataEntry): boolean {
// Known app -> category mappings (matches App Store categorisation) // Known app -> category mappings (matches App Store categorisation)
export const APP_CATEGORY_MAP: Record<string, string> = { export const APP_CATEGORY_MAP: Record<string, string> = {
'bitcoin-core': 'money', 'bitcoin-knots': 'money', 'bitcoin-ui': 'money', 'cuprate-ui': 'money', 'electrumx': 'money', 'electrs': 'money', 'bitcoin-core': 'money', 'bitcoin-knots': 'money', 'bitcoin-ui': 'money', 'cuprate': 'money', 'cuprate-ui': 'money', 'electrumx': 'money', 'electrs': 'money',
'lnd': 'money', 'mempool': 'money', 'mempool-web': 'money', 'btcpay-server': 'commerce', 'lnd': 'money', 'mempool': 'money', 'mempool-web': 'money', 'btcpay-server': 'commerce',
'fedimint': 'money', 'fedimint-gateway': 'money', 'fedimint': 'money', 'fedimint-gateway': 'money',
'indeedhub': 'media', 'jellyfin': 'media', 'photoprism': 'media', 'immich': 'media', 'indeedhub': 'media', 'jellyfin': 'media', 'photoprism': 'media', 'immich': 'media',
+4 -2
View File
@@ -14,8 +14,10 @@
// SERVICE_NAMES set that used to live in appsConfig.ts verbatim. // SERVICE_NAMES set that used to live in appsConfig.ts verbatim.
export const SERVICE_NAMES = new Set([ export const SERVICE_NAMES = new Set([
'dwn', 'archy-mempool-db', 'archy-btcpay-db', 'archy-nbxplorer', 'archy-tor', 'dwn', 'archy-mempool-db', 'archy-btcpay-db', 'archy-nbxplorer', 'archy-tor',
// Cuprate's daemon is the backend dependency of the Cuprate UI app. // Cuprate is presented as one user-facing app. Its companion container
'cuprate', // (archy-cuprate-ui) is the implementation detail; do not classify the
// primary package as a Service or it disappears from My Apps and loses its
// launch button during/after install.
// Headless backends with no user-facing UI: the Fedimint ecash client daemon, // Headless backends with no user-facing UI: the Fedimint ecash client daemon,
// the Nostr relay, and the Meshtastic LoRa daemon (its chat UI lives in the // the Nostr relay, and the Meshtastic LoRa daemon (its chat UI lives in the
// built-in Mesh tab) belong in Services, not My Apps. // built-in Mesh tab) belong in Services, not My Apps.