mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-30 20:14:49 +00:00
* feat: unified restart notification with reason-specific messaging Replace statusInfo.updated (bool) with serverInfo.restart (nullable enum) to unify all restart-needed scenarios under a single PatchDB field. Backend sets the restart reason in RPC handlers for hostname change (mdns), language change, kiosk toggle, and OS update download. Init clears it on boot. The update flow checks this field to prevent updates when a restart is already pending. Frontend shows a persistent action bar with reason-specific i18n messages instead of per-feature restart dialogs. For .local hostname changes, the existing "open new address" dialog is preserved — the restart toast appears after the user logs in on the new address. Also includes migration in v0_4_0_alpha_23 to remove statusInfo.updated and initialize serverInfo.restart. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix broken styling and improve settings layout * refactor: move restart field from ServerInfo to ServerStatus The restart reason belongs with other server state (shutting_down, restarting, update_progress) rather than on the top-level ServerInfo. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix PR comment --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Co-authored-by: Aiden McClelland <me@drbonez.dev>
Start SDK
The Start SDK (@start9labs/start-sdk) is a TypeScript framework for packaging services to run on StartOS. It provides a strongly-typed, builder-pattern API for defining every aspect of a service package: manifests, daemons, health checks, networking interfaces, actions, backups, dependencies, configuration, and more.
Features
- Type-safe manifest definitions - Declare your service's identity, metadata, images, volumes, and dependencies with full TypeScript inference.
- Daemon management - Define multi-process topologies with startup ordering, ready probes, and graceful shutdown via
Daemons.of().addDaemon(). - Health checks - Built-in checks for TCP port listening, HTTP(S) endpoints, and custom scripts, with configurable polling strategies (fixed interval, cooldown, adaptive).
- Network interfaces - Bind ports, export UI/API/P2P interfaces, and manage hostnames with MultiHost and ServiceInterfaceBuilder.
- User actions - Create interactive operations with validated form inputs (text, select, toggle, list, union/variants, and more) that users can trigger from the StartOS UI.
- Backup and restore - Rsync-based volume backups with exclude patterns and custom sync paths.
- Dependency management - Declare inter-service dependencies with version ranges, health check requirements, and volume mounts.
- Configuration file helpers - Read, write, and merge JSON, YAML, TOML, INI, and ENV files with type-safe
FileHelper. - Reactive subscriptions - Watch for changes to container IPs, SSL certificates, SMTP config, service status, and more with
const(),once(),watch(),onChange(), andwaitFor()patterns. - Extended versioning (ExVer) - Flavor-aware semantic versioning with range matching, supporting independent upstream and downstream version tracking.
- Internationalization - Built-in i18n support with locale fallback and parameter substitution.
- Container execution - Run commands in subcontainers with volume mounts, environment variables, and entrypoint overrides.
- Plugin system - Extensible plugin architecture (e.g.
url-v0for URL management).
Quick Start
import { setupManifest, buildManifest } from '@start9labs/start-sdk'
const manifest = setupManifest({
id: 'my-service',
title: 'My Service',
license: 'MIT',
// ...
})
export default buildManifest(manifest)
The primary entry point is the StartSdk facade:
import { StartSdk } from '@start9labs/start-sdk'
import { manifest } from './manifest'
export const sdk = StartSdk.of().withManifest(manifest).build(true)
From there, sdk exposes the full toolkit:
// Define daemons
export const main = sdk.setupMain(async ({ effects }) =>
sdk.Daemons.of(effects)
.addDaemon('primary', { /* ... */ })
)
// Define actions
export const setName = sdk.Action.withInput('set-name', /* ... */)
// Define interfaces
export const setInterfaces = sdk.setupInterfaces(async ({ effects }) => {
const multi = sdk.MultiHost.of(effects, 'web')
const origin = await multi.bindPort(80, { protocol: 'http' })
const ui = sdk.createInterface(effects, { name: 'Web UI', id: 'ui', /* ... */ })
return [await origin.export([ui])]
})
// Define backups
export const { createBackup, restoreBackup } = sdk.setupBackups(
async () => sdk.Backups.ofVolumes('main')
)
Packages
| Package | npm | Description |
|---|---|---|
package/ |
@start9labs/start-sdk |
Full SDK for service developers |
base/ |
@start9labs/start-sdk-base |
Core types, ABI definitions, and effects interface |
Documentation
For comprehensive packaging guides, tutorials, and API reference:
The packaging docs cover:
- Environment setup and prerequisites
- Project structure and conventions
- Manifest, main, interfaces, actions, and all other service modules
- File models and configuration management
- Versioning, migrations, and initialization
- Dependencies and cross-service communication
- Building and installing
.s9pkpackages
Contributing
See CONTRIBUTING.md for environment setup, building from source, testing, and development workflow.
Architecture
See ARCHITECTURE.md for a detailed overview of the SDK's internal structure, module responsibilities, and data flow.
License
MIT