Compare commits

..
2 Commits
Author SHA1 Message Date
spacesops b446cd5f69 0.3.1:0
Build Service / BuildPackage (push) Canceled after 0s
2026-08-28 16:55:15 -04:00
spacesopsandCursor 073344d4d1 0.3.0:1
Build Service / BuildPackage (push) Canceled after 0s
Group Actions and Config by category (Space-CLI, Bitcoin, Spaced,
Subspaces, Certrelay, Nacho) and build x86 + arm only.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-24 03:34:34 -04:00
33 changed files with 85 additions and 45 deletions
+1 -1
View File
@@ -1,3 +1,3 @@
ARCHES := x86
ARCHES := x86 arm
# overrides to s9pk.mk must precede the include statement
include node_modules/@start9labs/start-sdk/s9pk.mk
+7 -7
View File
@@ -37,8 +37,8 @@ through a browser-based terminal.
| Field | Value |
| --- | --- |
| Spaces image | `docker.io/horologger/spaces:v0.3.0` |
| Subspaces image | `docker.io/horologger/subs:v0.1.2c` |
| Spaces image | `docker.io/horologger/spaces:v0.3.1` |
| Subspaces image | `docker.io/horologger/subs:v0.1.2d` |
| Certrelay image | `docker.io/horologger/certrelay:v0.2.8` |
| Nacho image | `docker.io/horologger/nacho:v1.0.0b` |
| Architectures | `linux/amd64`, `linux/arm64` |
@@ -201,7 +201,7 @@ the same idempotent init logic runs and reuses the existing credentials in
6. **The web terminal is independent of spaced.** Gotty stays reachable even
when `spaced` is crash-looping, so you can always shell in to diagnose.
7. **Subspaces is opt-in.** Fresh installs do not run Subspaces. Run **Enable
Subspaces** to start it. It ships as the prebuilt `horologger/subs:v0.1.2c`
Subspaces** to start it. It ships as the prebuilt `horologger/subs:v0.1.2d`
image (no compile step), so enabling is fast — the daemons start as soon
as the image is on the box. Enabling runs three daemons, each with its own
StartOS interface: **subs** (Web UI + Subs API, 7777), **registry-server**
@@ -257,8 +257,8 @@ spaces balance
package_id: spaces
upstream_version: subspacesplus
images:
spaces: docker.io/horologger/spaces:v0.3.0
subspaces: docker.io/horologger/subs:v0.1.2c
spaces: docker.io/horologger/spaces:v0.3.1
subspaces: docker.io/horologger/subs:v0.1.2d
certrelay: docker.io/horologger/certrelay:v0.2.8
nacho: docker.io/horologger/nacho:v1.0.0b
architectures: [x86_64, aarch64]
@@ -293,12 +293,12 @@ spaced_env_vars:
- APP_USER
- APP_PASSWORD
spaces:
image: horologger/spaces:v0.3.0 # spaced, space-cli, gotty (terminal image)
image: horologger/spaces:v0.3.1 # spaced, space-cli, gotty (terminal image)
subspaces:
default_enabled: false # opt-in via Enable Subspaces action
store_field: enableSubspaces
subs_prover_default_enabled: false # separate toggle: set-subs-prover (store.enableSubsProver)
image: horologger/subs:v0.1.2c # prebuilt; no compile step
image: horologger/subs:v0.1.2d # prebuilt; no compile step
data_dir: /data/subspaces/data
wallet: default # loaded by subs, NOT created (create via space-cli first)
daemons: # three separate daemons, each its own interface
+2 -2
View File
@@ -80,8 +80,8 @@ Use **Show Registry API Keys** to retrieve the stored values later, or re-run
- **Mainnet only.** No testnet, signet, or regtest.
- **Container images** (see also the package manifest): the `spaced` runtime uses
`horologger/spaces:v0.3.0`; Subspaces, Certrelay, and Nacho use
`horologger/subs:v0.1.2c`, `horologger/certrelay:v0.2.8`, and
`horologger/spaces:v0.3.1`; Subspaces, Certrelay, and Nacho use
`horologger/subs:v0.1.2d`, `horologger/certrelay:v0.2.8`, and
`horologger/nacho:v1.0.0b`.
- The image's `docker_entrypoint.sh` is not used. `spaced` is managed by
StartOS, not started inside a `screen` session by login.
+14
View File
@@ -0,0 +1,14 @@
import { i18n } from './i18n'
/** Headers for the Actions and Config page (`ActionMetadata.group`). */
export const actionGroups = {
spaceCli: i18n('Space-CLI Web UI'),
bitcoin: i18n('Bitcoin'),
spaced: i18n('Spaced'),
subspaces: i18n('Subspaces'),
subspacesAuth: i18n('Subspaces Auth'),
subspacesProverAuth: i18n('Subspaces Prover Auth'),
subspacesRegistry: i18n('Subspaces Registry'),
certrelay: i18n('Certrelay'),
nacho: i18n('Nacho'),
}
+2 -1
View File
@@ -1,4 +1,5 @@
import { storeJson } from '../fileModels/storeJson'
import { actionGroups } from '../actionGroups'
import { i18n } from '../i18n'
import { sdk } from '../sdk'
import {
@@ -61,7 +62,7 @@ export const configureCertrelay = sdk.Action.withInput(
),
warning: null,
allowedStatuses: 'any',
group: null,
group: actionGroups.certrelay,
visibility: 'enabled',
}),
+2 -1
View File
@@ -1,4 +1,5 @@
import { storeJson } from '../fileModels/storeJson'
import { actionGroups } from '../actionGroups'
import { i18n } from '../i18n'
import { sdk } from '../sdk'
import {
@@ -90,7 +91,7 @@ export const configureNacho = sdk.Action.withInput(
),
warning: null,
allowedStatuses: 'any',
group: null,
group: actionGroups.nacho,
visibility: 'enabled',
}),
+2 -1
View File
@@ -1,4 +1,5 @@
import { storeJson } from '../fileModels/storeJson'
import { actionGroups } from '../actionGroups'
import { i18n } from '../i18n'
import { sdk } from '../sdk'
import { generateRegistryApiKeys } from '../utils'
@@ -15,7 +16,7 @@ export const createRegistryApiKeys = sdk.Action.withoutInput(
),
warning: null,
allowedStatuses: 'any',
group: null,
group: actionGroups.subspacesRegistry,
visibility: 'enabled',
}),
+2 -1
View File
@@ -1,4 +1,5 @@
import { storeJson } from '../fileModels/storeJson'
import { actionGroups } from '../actionGroups'
import { i18n } from '../i18n'
import { sdk } from '../sdk'
@@ -16,7 +17,7 @@ export const disableSubsAuth = sdk.Action.withoutInput(
),
warning: null,
allowedStatuses: 'any',
group: null,
group: actionGroups.subspacesAuth,
visibility: enabled === true ? 'enabled' : 'hidden',
}
},
+2 -1
View File
@@ -1,4 +1,5 @@
import { storeJson } from '../fileModels/storeJson'
import { actionGroups } from '../actionGroups'
import { i18n } from '../i18n'
import { sdk } from '../sdk'
@@ -16,7 +17,7 @@ export const disableSubsProverAuth = sdk.Action.withoutInput(
),
warning: null,
allowedStatuses: 'any',
group: null,
group: actionGroups.subspacesProverAuth,
visibility: enabled === true ? 'enabled' : 'hidden',
}
},
+2 -1
View File
@@ -1,4 +1,5 @@
import { storeJson } from '../fileModels/storeJson'
import { actionGroups } from '../actionGroups'
import { i18n } from '../i18n'
import { sdk } from '../sdk'
@@ -16,7 +17,7 @@ export const disableSubspaces = sdk.Action.withoutInput(
),
warning: null,
allowedStatuses: 'any',
group: null,
group: actionGroups.subspaces,
visibility: current === true ? 'enabled' : 'hidden',
}
},
+2 -1
View File
@@ -1,4 +1,5 @@
import { storeJson } from '../fileModels/storeJson'
import { actionGroups } from '../actionGroups'
import { i18n } from '../i18n'
import { sdk } from '../sdk'
import { randomPassword } from '../utils'
@@ -19,7 +20,7 @@ export const enableSubsAuth = sdk.Action.withoutInput(
),
warning: null,
allowedStatuses: 'any',
group: null,
group: actionGroups.subspacesAuth,
visibility: enabled === true ? 'hidden' : 'enabled',
}
},
+2 -1
View File
@@ -1,4 +1,5 @@
import { storeJson } from '../fileModels/storeJson'
import { actionGroups } from '../actionGroups'
import { i18n } from '../i18n'
import { sdk } from '../sdk'
import { randomPassword } from '../utils'
@@ -19,7 +20,7 @@ export const enableSubsProverAuth = sdk.Action.withoutInput(
),
warning: null,
allowedStatuses: 'any',
group: null,
group: actionGroups.subspacesProverAuth,
visibility: enabled === true ? 'hidden' : 'enabled',
}
},
+2 -1
View File
@@ -1,4 +1,5 @@
import { storeJson } from '../fileModels/storeJson'
import { actionGroups } from '../actionGroups'
import { i18n } from '../i18n'
import { sdk } from '../sdk'
@@ -16,7 +17,7 @@ export const enableSubspaces = sdk.Action.withoutInput(
),
warning: null,
allowedStatuses: 'any',
group: null,
group: actionGroups.subspaces,
visibility: current === true ? 'hidden' : 'enabled',
}
},
+2 -1
View File
@@ -1,4 +1,5 @@
import { storeJson } from '../fileModels/storeJson'
import { actionGroups } from '../actionGroups'
import { i18n } from '../i18n'
import { sdk } from '../sdk'
import { dataDir, SPACED_CHAIN } from '../utils'
@@ -18,7 +19,7 @@ export const exportWallet = sdk.Action.withoutInput(
),
warning: null,
allowedStatuses: 'only-running',
group: null,
group: actionGroups.spaced,
visibility: 'enabled',
}),
+2 -1
View File
@@ -1,4 +1,5 @@
import { storeJson } from '../fileModels/storeJson'
import { actionGroups } from '../actionGroups'
import { i18n } from '../i18n'
import { sdk } from '../sdk'
import { dataDir, SPACED_CHAIN } from '../utils'
@@ -37,7 +38,7 @@ export const importWallet = sdk.Action.withInput(
'Existing /data/mainnet/wallets_backup/default.json and /data/mainnet/wallets/default will be renamed with .bakNNN suffixes before the import. The active spaced daemon will load the imported wallet on success.',
),
allowedStatuses: 'only-running',
group: null,
group: actionGroups.spaced,
visibility: 'enabled',
}),
+2 -1
View File
@@ -1,4 +1,5 @@
import { storeJson } from '../fileModels/storeJson'
import { actionGroups } from '../actionGroups'
import { i18n } from '../i18n'
import { sdk } from '../sdk'
import { APP_USER, randomPassword } from '../utils'
@@ -15,7 +16,7 @@ export const resetPassword = sdk.Action.withoutInput(
),
warning: null,
allowedStatuses: 'any',
group: null,
group: actionGroups.spaceCli,
visibility: 'enabled',
}),
+2 -1
View File
@@ -1,3 +1,4 @@
import { actionGroups } from '../actionGroups'
import { i18n } from '../i18n'
import { sdk } from '../sdk'
import { dataDir, SPACED_CHAIN } from '../utils'
@@ -16,7 +17,7 @@ export const resetSpacedState = sdk.Action.withoutInput(
"This deletes spaced's on-disk index. The next start will resync from spaces' anchor and can take a while. store.json (passwords + RPC credentials) is preserved.",
),
allowedStatuses: 'any',
group: null,
group: actionGroups.spaced,
visibility: 'enabled',
}),
+2 -1
View File
@@ -1,3 +1,4 @@
import { actionGroups } from '../actionGroups'
import { i18n } from '../i18n'
import { sdk } from '../sdk'
import { dataDir, SUBSPACES_DIR } from '../utils'
@@ -16,7 +17,7 @@ export const resetSubspacesState = sdk.Action.withoutInput(
'This deletes all local Subspaces state — any handles/proofs stored on disk will be lost. The binaries ship in the image, so nothing needs to be re-downloaded. The spaces wallet on spaced is preserved.',
),
allowedStatuses: 'any',
group: null,
group: actionGroups.subspaces,
visibility: 'enabled',
}),
+2 -1
View File
@@ -1,4 +1,5 @@
import { storeJson } from '../fileModels/storeJson'
import { actionGroups } from '../actionGroups'
import { i18n } from '../i18n'
import { sdk } from '../sdk'
import {
@@ -17,7 +18,7 @@ export const setBitcoinRpc = sdk.Action.withoutInput(
description: i18n('Re-run the bitcoind RPC credential setup for Spaces'),
warning: null,
allowedStatuses: 'any',
group: null,
group: actionGroups.bitcoin,
visibility: 'enabled',
}),
+2 -1
View File
@@ -1,4 +1,5 @@
import { storeJson } from '../fileModels/storeJson'
import { actionGroups } from '../actionGroups'
import { i18n } from '../i18n'
import { sdk } from '../sdk'
import { randomPassword } from '../utils'
@@ -50,7 +51,7 @@ export const setSubsCredentials = sdk.Action.withInput(
),
warning: null,
allowedStatuses: 'any',
group: null,
group: actionGroups.subspacesAuth,
visibility: 'enabled',
}),
+2 -1
View File
@@ -1,4 +1,5 @@
import { storeJson } from '../fileModels/storeJson'
import { actionGroups } from '../actionGroups'
import { i18n } from '../i18n'
import { sdk } from '../sdk'
@@ -28,7 +29,7 @@ export const setSubsProver = sdk.Action.withInput(
),
warning: null,
allowedStatuses: 'any',
group: null,
group: actionGroups.subspaces,
visibility: 'enabled',
}),
+2 -1
View File
@@ -1,4 +1,5 @@
import { storeJson } from '../fileModels/storeJson'
import { actionGroups } from '../actionGroups'
import { i18n } from '../i18n'
import { sdk } from '../sdk'
import { randomPassword } from '../utils'
@@ -50,7 +51,7 @@ export const setSubsProverCredentials = sdk.Action.withInput(
),
warning: null,
allowedStatuses: 'any',
group: null,
group: actionGroups.subspacesProverAuth,
visibility: 'enabled',
}),
+2 -1
View File
@@ -1,4 +1,5 @@
import { storeJson } from '../fileModels/storeJson'
import { actionGroups } from '../actionGroups'
import { i18n } from '../i18n'
import { sdk } from '../sdk'
import { APP_USER } from '../utils'
@@ -15,7 +16,7 @@ export const showCredentials = sdk.Action.withoutInput(
),
warning: null,
allowedStatuses: 'any',
group: null,
group: actionGroups.spaceCli,
visibility: 'hidden',
}),
+2 -1
View File
@@ -1,4 +1,5 @@
import { storeJson } from '../fileModels/storeJson'
import { actionGroups } from '../actionGroups'
import { i18n } from '../i18n'
import { sdk } from '../sdk'
import { APP_USER } from '../utils'
@@ -15,7 +16,7 @@ export const showPassword = sdk.Action.withoutInput(
),
warning: null,
allowedStatuses: 'any',
group: null,
group: actionGroups.spaceCli,
visibility: 'enabled',
}),
+2 -1
View File
@@ -1,4 +1,5 @@
import { storeJson } from '../fileModels/storeJson'
import { actionGroups } from '../actionGroups'
import { i18n } from '../i18n'
import { sdk } from '../sdk'
@@ -14,7 +15,7 @@ export const showRegistryApiKeys = sdk.Action.withoutInput(
),
warning: null,
allowedStatuses: 'any',
group: null,
group: actionGroups.subspacesRegistry,
visibility: 'enabled',
}),
+2 -1
View File
@@ -1,4 +1,5 @@
import { storeJson } from '../fileModels/storeJson'
import { actionGroups } from '../actionGroups'
import { i18n } from '../i18n'
import { sdk } from '../sdk'
import { spacedRpcPort } from '../utils'
@@ -15,7 +16,7 @@ export const showSpacedCredentials = sdk.Action.withoutInput(
),
warning: null,
allowedStatuses: 'any',
group: null,
group: actionGroups.spaced,
visibility: 'enabled',
}),
+2 -1
View File
@@ -1,4 +1,5 @@
import { storeJson } from '../fileModels/storeJson'
import { actionGroups } from '../actionGroups'
import { i18n } from '../i18n'
import { sdk } from '../sdk'
import { SUBSPACES_UI_PORT } from '../utils'
@@ -15,7 +16,7 @@ export const showSubsCredentials = sdk.Action.withoutInput(
),
warning: null,
allowedStatuses: 'any',
group: null,
group: actionGroups.subspacesAuth,
visibility: 'enabled',
}),
+2 -1
View File
@@ -1,4 +1,5 @@
import { storeJson } from '../fileModels/storeJson'
import { actionGroups } from '../actionGroups'
import { i18n } from '../i18n'
import { sdk } from '../sdk'
import { SUBSPACES_PROVER_PORT } from '../utils'
@@ -15,7 +16,7 @@ export const showSubsProverCredentials = sdk.Action.withoutInput(
),
warning: null,
allowedStatuses: 'any',
group: null,
group: actionGroups.subspacesProverAuth,
visibility: 'enabled',
}),
+2 -1
View File
@@ -1,4 +1,5 @@
import { storeJson } from '../fileModels/storeJson'
import { actionGroups } from '../actionGroups'
import { i18n } from '../i18n'
import { sdk } from '../sdk'
import { dataDir, SPACED_CHAIN } from '../utils'
@@ -15,7 +16,7 @@ export const syncStatus = sdk.Action.withoutInput(
),
warning: null,
allowedStatuses: 'only-running',
group: null,
group: actionGroups.spaced,
visibility: 'enabled',
}),
+2 -1
View File
@@ -1,4 +1,5 @@
import { readFile } from 'fs/promises'
import { actionGroups } from '../actionGroups'
import { i18n } from '../i18n'
import { sdk } from '../sdk'
import { dataDir } from '../utils'
@@ -36,7 +37,7 @@ export const uploadSupportPdf = sdk.Action.withInput(
),
warning: null,
allowedStatuses: 'any',
group: null,
group: actionGroups.nacho,
visibility: 'enabled',
}),
+5
View File
@@ -308,6 +308,11 @@ const dict = {
223,
'Subspaces registry-server requires REGISTRY_API_KEY and SUBSD_API_KEY before it can start':
224,
Bitcoin: 225,
Spaced: 226,
Subspaces: 227,
'Subspaces Auth': 228,
'Subspaces Prover Auth': 229,
} as const
/**
+2 -2
View File
@@ -14,11 +14,11 @@ export const manifest = setupManifest({
volumes: ['main'],
images: {
spaces: {
source: { dockerTag: 'horologger/spaces:v0.3.0' },
source: { dockerTag: 'horologger/spaces:v0.3.1' },
arch: ['x86_64', 'aarch64'],
},
subspaces: {
source: { dockerTag: 'horologger/subs:v0.1.2c' },
source: { dockerTag: 'horologger/subs:v0.1.2d' },
arch: ['x86_64', 'aarch64'],
},
certrelay: {
+2 -7
View File
@@ -1,14 +1,9 @@
import { IMPOSSIBLE, VersionInfo } from '@start9labs/start-sdk'
export const current = VersionInfo.of({
version: '0.3.0:0',
version: '0.3.1:0',
releaseNotes: {
en_US: `Update to upstream Spaces **0.3.0** (\`horologger/spaces:v0.3.0\`). Also bundles \`subs:v0.1.2c\`, \`certrelay:v0.2.8\`, and \`nacho:v1.0.0b\`.
**Wrapper**
- Add **Create Registry API Keys** / **Show Registry API Keys** for the embedded \`registry-server\` (\`REGISTRY_API_KEY\` + \`SUBSD_API_KEY\`; required and must differ)
- Remove **Configure Subspaces** and \`SUBS_PUBLISH_REQUIRE_FINALIZED\`
en_US: `Update to upstream Spaces **0.3.1** (\`horologger/spaces:v0.3.1\`). Also bundles \`subs:v0.1.2d\` (\`certrelay:v0.2.8\` and \`nacho:v1.0.0b\` unchanged).
Requires StartOS 0.4.0-beta.10 (\`start-sdk\` 2.0.9).`,
},