Compare commits
9
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
700d39c425 | ||
|
|
4272c47ee5 | ||
|
|
c7cb043485 | ||
|
|
4dfe79290e | ||
|
|
d3e3df6d24 | ||
|
|
969570e38b | ||
|
|
b73d646db5 | ||
|
|
8c37ff412c | ||
|
|
06bf359535 |
@@ -2,6 +2,12 @@
|
||||
|
||||
## Unreleased
|
||||
|
||||
## v1.8.15-alpha (2026-09-13)
|
||||
|
||||
- Cuprate is presented as one user-facing app in My Apps, including its UI launch button; the generated dashboard companion is hidden as an implementation detail instead of appearing under Services.
|
||||
- Added regression coverage for Cuprate install and installed-state grouping.
|
||||
- Release validation was rerun on the corrected tree before OTA and ISO publication.
|
||||
|
||||
## v1.8.14-alpha (2026-09-13)
|
||||
|
||||
- **Cuprate gains a first-party companion dashboard.** The Monero node now has a Bitcoin-style status UI, safe app grouping, a 450 GB disk-safety gate, and a restricted RPC that is never exposed as a launch page.
|
||||
|
||||
Generated
+1
-1
@@ -104,7 +104,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "archipelago"
|
||||
version = "1.8.14-alpha"
|
||||
version = "1.8.15-alpha"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"archipelago-container",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "archipelago"
|
||||
version = "1.8.14-alpha"
|
||||
version = "1.8.15-alpha"
|
||||
edition = "2021"
|
||||
license.workspace = true
|
||||
description = "Archipelago Bitcoin Node OS - Native backend"
|
||||
|
||||
Generated
+2
-2
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "neode-ui",
|
||||
"version": "1.8.14-alpha",
|
||||
"version": "1.8.15-alpha",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "neode-ui",
|
||||
"version": "1.8.14-alpha",
|
||||
"version": "1.8.15-alpha",
|
||||
"dependencies": {
|
||||
"@scure/bip39": "^2.2.0",
|
||||
"@types/dompurify": "^3.0.5",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "neode-ui",
|
||||
"private": true,
|
||||
"version": "1.8.14-alpha",
|
||||
"version": "1.8.15-alpha",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"start": "./start-dev.sh",
|
||||
|
||||
@@ -78,12 +78,11 @@ describe('appsConfig service filtering', () => {
|
||||
|
||||
it('shows Cuprate as one My Apps entry while hiding its daemon dependency', () => {
|
||||
const entries: Array<[string, PackageDataEntry]> = [
|
||||
['cuprate-ui', makePkg('cuprate-ui', 'Cuprate UI', 'money')],
|
||||
['cuprate', makePkg('cuprate', 'Cuprate daemon', 'money')],
|
||||
['cuprate', makePkg('cuprate', 'Cuprate', '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-ui'])
|
||||
expect(filterEntriesForTab(entries, 'services', 'all').map(([id]) => id)).toEqual(['cuprate'])
|
||||
expect(filterEntriesForTab(entries, 'apps', 'all').map(([id]) => id)).toEqual(['cuprate'])
|
||||
expect(filterEntriesForTab(entries, 'services', 'all').map(([id]) => id)).toEqual([])
|
||||
})
|
||||
|
||||
it('falls back to packaged app icon when static icon token is not a path', () => {
|
||||
|
||||
@@ -20,6 +20,10 @@ export const isServiceContainer = sharedIsServiceContainer
|
||||
|
||||
const INTERNAL_TOOLING_NAMES = new Set([
|
||||
'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 {
|
||||
@@ -37,7 +41,7 @@ export function isServicePackage(id: string, pkg?: PackageDataEntry): boolean {
|
||||
|
||||
// Known app -> category mappings (matches App Store categorisation)
|
||||
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',
|
||||
'fedimint': 'money', 'fedimint-gateway': 'money',
|
||||
'indeedhub': 'media', 'jellyfin': 'media', 'photoprism': 'media', 'immich': 'media',
|
||||
|
||||
@@ -14,8 +14,10 @@
|
||||
// SERVICE_NAMES set that used to live in appsConfig.ts verbatim.
|
||||
export const SERVICE_NAMES = new Set([
|
||||
'dwn', 'archy-mempool-db', 'archy-btcpay-db', 'archy-nbxplorer', 'archy-tor',
|
||||
// Cuprate's daemon is the backend dependency of the Cuprate UI app.
|
||||
'cuprate',
|
||||
// Cuprate is presented as one user-facing app. Its companion container
|
||||
// (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,
|
||||
// the Nostr relay, and the Meshtastic LoRa daemon (its chat UI lives in the
|
||||
// built-in Mesh tab) belong in Services, not My Apps.
|
||||
|
||||
@@ -362,6 +362,17 @@ init()
|
||||
</button>
|
||||
</div>
|
||||
<div class="overflow-y-auto flex-1 min-h-0 space-y-6 pr-1">
|
||||
<!-- v1.8.15-alpha -->
|
||||
<div>
|
||||
<div class="flex items-center gap-2 mb-3">
|
||||
<span class="text-xs font-mono px-2 py-0.5 rounded bg-orange-500/20 text-orange-300">v1.8.15-alpha</span>
|
||||
<span class="text-xs text-white/40">September 13, 2026</span>
|
||||
</div>
|
||||
<div class="space-y-3 text-sm text-white/80 pl-3 border-l border-white/10">
|
||||
<p>Cuprate is presented as one user-facing app in My Apps, including its UI launch button; the generated dashboard companion is hidden as an implementation detail instead of appearing under Services.</p>
|
||||
<p>Added regression coverage for Cuprate install and installed-state grouping.</p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- v1.8.14-alpha -->
|
||||
<div>
|
||||
<div class="flex items-center gap-2 mb-3">
|
||||
|
||||
+17
-17
@@ -1,29 +1,29 @@
|
||||
{
|
||||
"changelog": [
|
||||
"**GitWorkshop installs reliably on fresh nodes.** The app is classified as a user-facing app while its install placeholder is being created, so it remains visible under My Apps instead of Services.",
|
||||
"**Fresh GitWorkshop installs build the correct image.** The production orchestrator handles its bundled build context instead of sending the local image reference through the legacy registry-pull path.",
|
||||
"**Curated app classification is regression-tested.** Every user-facing app remains in My Apps during installation, while headless services stay in Services."
|
||||
"Cuprate is presented as one user-facing app in My Apps, including its UI launch button; the generated dashboard companion is hidden as an implementation detail instead of appearing under Services.",
|
||||
"Added regression coverage for Cuprate install and installed-state grouping.",
|
||||
"Release validation was rerun on the corrected tree before OTA and ISO publication."
|
||||
],
|
||||
"components": [
|
||||
{
|
||||
"current_version": "1.8.13-alpha",
|
||||
"download_url": "https://source.archipelago-foundation.org/lfg2025/archy/releases/download/v1.8.13-alpha/archipelago",
|
||||
"current_version": "1.8.15-alpha",
|
||||
"download_url": "https://source.archipelago-foundation.org/lfg2025/archy/releases/download/v1.8.15-alpha/archipelago",
|
||||
"name": "archipelago",
|
||||
"new_version": "1.8.13-alpha",
|
||||
"sha256": "832c7e75b395f94f919a21d1ad7d32d367e1ef84a0e0995b4e8fe87268aa21a4",
|
||||
"size_bytes": 64585424
|
||||
"new_version": "1.8.15-alpha",
|
||||
"sha256": "3eee71563337f20cb348529925c58b8227afec796783a69176e0b59b9e113c91",
|
||||
"size_bytes": 64571544
|
||||
},
|
||||
{
|
||||
"current_version": "1.8.13-alpha",
|
||||
"download_url": "https://source.archipelago-foundation.org/lfg2025/archy/releases/download/v1.8.13-alpha/archipelago-frontend-1.8.13-alpha.tar.gz",
|
||||
"name": "archipelago-frontend-1.8.13-alpha.tar.gz",
|
||||
"new_version": "1.8.13-alpha",
|
||||
"sha256": "d0159b61f84eb30013634a97177801474376dddb1189024b94f16236ce7ff538",
|
||||
"size_bytes": 97915796
|
||||
"current_version": "1.8.15-alpha",
|
||||
"download_url": "https://source.archipelago-foundation.org/lfg2025/archy/releases/download/v1.8.15-alpha/archipelago-frontend-1.8.15-alpha.tar.gz",
|
||||
"name": "archipelago-frontend-1.8.15-alpha.tar.gz",
|
||||
"new_version": "1.8.15-alpha",
|
||||
"sha256": "86a32ef3334b03c197e47d9d28f4435c6f2fa7c4ccacc839a8fc4a0a749495dc",
|
||||
"size_bytes": 98797600
|
||||
}
|
||||
],
|
||||
"release_date": "2026-09-12",
|
||||
"signature": "45a322e793a2fc7565cc148f14efbbcf03e0c934183590375368091368ffe49ed2a7e9962692caf54b3432c71976a6c1b0f06a48cf8c4634c7b2e573e5782a0f",
|
||||
"release_date": "2026-09-13",
|
||||
"signature": "5e13396e2f33571f136bb1a9ea0356486b3d42c6ba99ee5d33990cd565d9b1178f61eaf6a70a937a006e7de3fd388bcebd63f2daca4bb28accc1b810d8455d03",
|
||||
"signed_by": "did:key:z6Mkfu5LT8d4DjETtrkATvHh9Dvcbnr7zBCUwfau8Sw7DLWT",
|
||||
"version": "1.8.13-alpha"
|
||||
"version": "1.8.15-alpha"
|
||||
}
|
||||
|
||||
+3247
-3245
File diff suppressed because one or more lines are too long
+17
-17
@@ -1,29 +1,29 @@
|
||||
{
|
||||
"changelog": [
|
||||
"**GitWorkshop installs reliably on fresh nodes.** The app is classified as a user-facing app while its install placeholder is being created, so it remains visible under My Apps instead of Services.",
|
||||
"**Fresh GitWorkshop installs build the correct image.** The production orchestrator handles its bundled build context instead of sending the local image reference through the legacy registry-pull path.",
|
||||
"**Curated app classification is regression-tested.** Every user-facing app remains in My Apps during installation, while headless services stay in Services."
|
||||
"Cuprate is presented as one user-facing app in My Apps, including its UI launch button; the generated dashboard companion is hidden as an implementation detail instead of appearing under Services.",
|
||||
"Added regression coverage for Cuprate install and installed-state grouping.",
|
||||
"Release validation was rerun on the corrected tree before OTA and ISO publication."
|
||||
],
|
||||
"components": [
|
||||
{
|
||||
"current_version": "1.8.13-alpha",
|
||||
"download_url": "https://source.archipelago-foundation.org/lfg2025/archy/releases/download/v1.8.13-alpha/archipelago",
|
||||
"current_version": "1.8.15-alpha",
|
||||
"download_url": "https://source.archipelago-foundation.org/lfg2025/archy/releases/download/v1.8.15-alpha/archipelago",
|
||||
"name": "archipelago",
|
||||
"new_version": "1.8.13-alpha",
|
||||
"sha256": "832c7e75b395f94f919a21d1ad7d32d367e1ef84a0e0995b4e8fe87268aa21a4",
|
||||
"size_bytes": 64585424
|
||||
"new_version": "1.8.15-alpha",
|
||||
"sha256": "3eee71563337f20cb348529925c58b8227afec796783a69176e0b59b9e113c91",
|
||||
"size_bytes": 64571544
|
||||
},
|
||||
{
|
||||
"current_version": "1.8.13-alpha",
|
||||
"download_url": "https://source.archipelago-foundation.org/lfg2025/archy/releases/download/v1.8.13-alpha/archipelago-frontend-1.8.13-alpha.tar.gz",
|
||||
"name": "archipelago-frontend-1.8.13-alpha.tar.gz",
|
||||
"new_version": "1.8.13-alpha",
|
||||
"sha256": "d0159b61f84eb30013634a97177801474376dddb1189024b94f16236ce7ff538",
|
||||
"size_bytes": 97915796
|
||||
"current_version": "1.8.15-alpha",
|
||||
"download_url": "https://source.archipelago-foundation.org/lfg2025/archy/releases/download/v1.8.15-alpha/archipelago-frontend-1.8.15-alpha.tar.gz",
|
||||
"name": "archipelago-frontend-1.8.15-alpha.tar.gz",
|
||||
"new_version": "1.8.15-alpha",
|
||||
"sha256": "86a32ef3334b03c197e47d9d28f4435c6f2fa7c4ccacc839a8fc4a0a749495dc",
|
||||
"size_bytes": 98797600
|
||||
}
|
||||
],
|
||||
"release_date": "2026-09-12",
|
||||
"signature": "45a322e793a2fc7565cc148f14efbbcf03e0c934183590375368091368ffe49ed2a7e9962692caf54b3432c71976a6c1b0f06a48cf8c4634c7b2e573e5782a0f",
|
||||
"release_date": "2026-09-13",
|
||||
"signature": "5e13396e2f33571f136bb1a9ea0356486b3d42c6ba99ee5d33990cd565d9b1178f61eaf6a70a937a006e7de3fd388bcebd63f2daca4bb28accc1b810d8455d03",
|
||||
"signed_by": "did:key:z6Mkfu5LT8d4DjETtrkATvHh9Dvcbnr7zBCUwfau8Sw7DLWT",
|
||||
"version": "1.8.13-alpha"
|
||||
"version": "1.8.15-alpha"
|
||||
}
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
{
|
||||
"changelog": [
|
||||
"**Cuprate gains a first-party companion dashboard.** The Monero node now has a Bitcoin-style status UI, safe app grouping, a 450 GB disk-safety gate, and a restricted RPC that is never exposed as a launch page.",
|
||||
"**Bitcoin Core Tor enrollment uses the correct protocol identity.** `bitcoin-core` is forwarded on port 8333 and resolves to its own hidden-service directory without disturbing legacy Bitcoin aliases.",
|
||||
"**GitWorkshop opens Archipelago’s canonical ngit repository by default.** The launcher and registry promotion use the full maintainer/relay/`archy` coordinate, with regression coverage for Companion and browser-tab launches.",
|
||||
"**Release validation is stricter.** The registry gate now checks the complete canonical source deep link, and the merged candidate passed the full frontend and focused backend test suites."
|
||||
],
|
||||
"components": [
|
||||
{
|
||||
"current_version": "1.8.14-alpha",
|
||||
"download_url": "https://source.archipelago-foundation.org/lfg2025/archy/releases/download/v1.8.14-alpha/archipelago",
|
||||
"name": "archipelago",
|
||||
"new_version": "1.8.14-alpha",
|
||||
"sha256": "3d8e5e7c79a261649e89c4f5ba8d90db9057ebbb002919a812ca82f664b315bf",
|
||||
"size_bytes": 64568360
|
||||
},
|
||||
{
|
||||
"current_version": "1.8.14-alpha",
|
||||
"download_url": "https://source.archipelago-foundation.org/lfg2025/archy/releases/download/v1.8.14-alpha/archipelago-frontend-1.8.14-alpha.tar.gz",
|
||||
"name": "archipelago-frontend-1.8.14-alpha.tar.gz",
|
||||
"new_version": "1.8.14-alpha",
|
||||
"sha256": "e1c490e52571bf9238435e5986792c6bd602fd7e398783546f7592aa921d3386",
|
||||
"size_bytes": 98792963
|
||||
}
|
||||
],
|
||||
"release_date": "2026-09-13",
|
||||
"signature": "dacfdd2707e415af8a42306a63658a7d41cdfeba29d43802d465d18f00a747ecbfa54ea4ee8ed1eedf94d4f30371453fd9c9d475af9d6a62eac4e2c8e783b405",
|
||||
"signed_by": "did:key:z6Mkfu5LT8d4DjETtrkATvHh9Dvcbnr7zBCUwfau8Sw7DLWT",
|
||||
"version": "1.8.14-alpha"
|
||||
}
|
||||
@@ -53,24 +53,33 @@ if [ -x "$PROJECT_ROOT/core/target/release/archipelago" ]; then
|
||||
fi
|
||||
|
||||
remote_url=$(git -C "$PROJECT_ROOT" remote get-url "$REMOTE")
|
||||
# https is accepted as well as http. Requiring http:// meant the only remote
|
||||
# whose credential actually works for git push (the https one) was rejected,
|
||||
# while the http remote it forced you to use had a dead token — so publishing
|
||||
# failed on auth after the manifest had already passed every check
|
||||
# (v1.7.121-alpha, 2026-08-04). The scheme is carried through to the API URL
|
||||
# rather than assumed.
|
||||
# Remote URLs are public metadata: ngit can include them in repository
|
||||
# announcements. Keep credentials in Git's credential helper, never in URLs.
|
||||
case "$remote_url" in
|
||||
http://*@*|https://*@*) ;;
|
||||
*) fail "$REMOTE must be an authenticated http(s):// Gitea remote URL for API uploads" ;;
|
||||
http://*@*|https://*@*) fail "$REMOTE embeds credentials; move them to a Git credential helper and remove them from the remote URL" ;;
|
||||
http://*|https://*) ;;
|
||||
*) fail "$REMOTE must be an http(s):// Gitea remote URL for API uploads" ;;
|
||||
esac
|
||||
|
||||
scheme=${remote_url%%://*}
|
||||
rest=${remote_url#*://}
|
||||
auth=${rest%%@*}
|
||||
host_path=${rest#*@}
|
||||
host_path=${remote_url#*://}
|
||||
host=${host_path%%/*}
|
||||
repo_path=${host_path#*/}
|
||||
repo_path=${repo_path%.git}
|
||||
credential=$(printf 'url=%s\n\n' "$remote_url" | GIT_TERMINAL_PROMPT=0 git -C "$PROJECT_ROOT" credential fill) \
|
||||
|| fail "no Git credential available for $REMOTE; configure a credential helper first"
|
||||
auth_user=""
|
||||
auth_password=""
|
||||
while IFS= read -r field; do
|
||||
case "$field" in
|
||||
username=*) auth_user=${field#username=} ;;
|
||||
password=*) auth_password=${field#password=} ;;
|
||||
esac
|
||||
done <<< "$credential"
|
||||
[ -n "$auth_user" ] && [ -n "$auth_password" ] \
|
||||
|| fail "Git credential helper did not provide a username and password for $REMOTE"
|
||||
auth="$auth_user:$auth_password"
|
||||
unset credential auth_user auth_password
|
||||
api="$scheme://$host/api/v1/repos/$repo_path"
|
||||
release_url="$api/releases/tags/v${VERSION}"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user