mid coding commit

This commit is contained in:
zazawowow
2026-01-24 22:59:20 +00:00
parent 64cc3bc7fb
commit 731cd67cfb
2228 changed files with 135554 additions and 18 deletions

View File

@@ -0,0 +1,478 @@
// Dummy apps data for first launch
// This can be easily replaced with real package data later
// Similar to how atob and k484 are handled
import type { PackageDataEntry } from '../types/api'
import { PackageState, ServiceStatus } from '../types/api'
export const dummyApps: Record<string, PackageDataEntry> = {
'bitcoin': {
state: PackageState.Running,
'static-files': {
license: 'MIT',
instructions: 'Bitcoin Core node for the Neode network',
icon: '/assets/img/app-icons/bitcoin.svg'
},
manifest: {
id: 'bitcoin',
title: 'Bitcoin Core',
version: '24.0.0',
description: {
short: 'Full Bitcoin node implementation',
long: 'Bitcoin Core is the reference implementation of Bitcoin. It provides a full node implementation that validates and relays transactions, maintains the blockchain, and serves as a wallet.'
},
'release-notes': 'Initial release',
license: 'MIT',
'wrapper-repo': 'https://github.com/Start9Labs/bitcoind-startos',
'upstream-repo': 'https://github.com/bitcoin/bitcoin',
'support-site': 'https://github.com/bitcoin/bitcoin/issues',
'marketing-site': 'https://bitcoin.org',
'donation-url': null
},
installed: {
'current-dependents': {},
'current-dependencies': {},
'last-backup': null,
'interface-addresses': {
main: {
'tor-address': 'bitcoin.onion',
'lan-address': 'http://localhost:8332'
}
},
status: ServiceStatus.Running
}
},
'btcpay-server': {
state: PackageState.Running,
'static-files': {
license: 'MIT',
instructions: 'BTCPay Server payment processor',
icon: '/assets/img/app-icons/btcpay-server.png'
},
manifest: {
id: 'btcpay-server',
title: 'BTCPay Server',
version: '1.12.0',
description: {
short: 'Self-hosted Bitcoin payment processor',
long: 'BTCPay Server is a free, open-source cryptocurrency payment processor. Accept Bitcoin payments without intermediaries or fees. Complete merchant solution with invoicing, point of sale, and more.'
},
'release-notes': 'Initial release',
license: 'MIT',
'wrapper-repo': 'https://github.com/Start9Labs/btcpayserver-startos',
'upstream-repo': 'https://github.com/btcpayserver/btcpayserver',
'support-site': 'https://github.com/btcpayserver/btcpayserver/issues',
'marketing-site': 'https://btcpayserver.org',
'donation-url': null
},
installed: {
'current-dependents': {},
'current-dependencies': {},
'last-backup': null,
'interface-addresses': {
main: {
'tor-address': 'btcpay.onion',
'lan-address': 'http://localhost:14142'
}
},
status: ServiceStatus.Running
}
},
'homeassistant': {
state: PackageState.Running,
'static-files': {
license: 'Apache-2.0',
instructions: 'Home automation platform',
icon: '/assets/img/app-icons/homeassistant.png'
},
manifest: {
id: 'homeassistant',
title: 'Home Assistant',
version: '2024.1.0',
description: {
short: 'Open source home automation platform',
long: 'Home Assistant is an open-source home automation platform running on Python. It tracks and controls all devices at home and offers a platform for automating control.'
},
'release-notes': 'Initial release',
license: 'Apache-2.0',
'wrapper-repo': 'https://github.com/Start9Labs/home-assistant-startos',
'upstream-repo': 'https://github.com/home-assistant/core',
'support-site': 'https://github.com/home-assistant/core/issues',
'marketing-site': 'https://www.home-assistant.io',
'donation-url': null
},
installed: {
'current-dependents': {},
'current-dependencies': {},
'last-backup': null,
'interface-addresses': {
main: {
'tor-address': 'homeassistant.onion',
'lan-address': 'http://localhost:8123'
}
},
status: ServiceStatus.Running
}
},
'grafana': {
state: PackageState.Running,
'static-files': {
license: 'Apache-2.0',
instructions: 'Analytics and monitoring platform',
icon: '/assets/img/grafana.png'
},
manifest: {
id: 'grafana',
title: 'Grafana',
version: '10.2.0',
description: {
short: 'Analytics and monitoring platform',
long: 'Grafana is an open-source analytics and monitoring platform. Create dashboards, query metrics, and visualize data from multiple sources.'
},
'release-notes': 'Initial release',
license: 'Apache-2.0',
'wrapper-repo': 'https://github.com/grafana/grafana',
'upstream-repo': 'https://github.com/grafana/grafana',
'support-site': 'https://github.com/grafana/grafana/issues',
'marketing-site': 'https://grafana.com',
'donation-url': null
},
installed: {
'current-dependents': {},
'current-dependencies': {},
'last-backup': null,
'interface-addresses': {
main: {
'tor-address': 'grafana.onion',
'lan-address': 'http://localhost:3000'
}
},
status: ServiceStatus.Running
}
},
'endurain': {
state: PackageState.Stopped,
'static-files': {
license: 'MIT',
instructions: 'Endurain application',
icon: '/assets/img/endurain.png'
},
manifest: {
id: 'endurain',
title: 'Endurain',
version: '1.0.0',
description: {
short: 'Endurain application platform',
long: 'Endurain provides a platform for decentralized applications and services.'
},
'release-notes': 'Initial release',
license: 'MIT',
'wrapper-repo': 'https://github.com/endurain/endurain',
'upstream-repo': 'https://github.com/endurain/endurain',
'support-site': 'https://github.com/endurain/endurain/issues',
'marketing-site': 'https://endurain.io',
'donation-url': null
},
installed: {
'current-dependents': {},
'current-dependencies': {},
'last-backup': null,
'interface-addresses': {
main: {
'tor-address': 'endurain.onion',
'lan-address': 'http://localhost:8080'
}
},
status: ServiceStatus.Stopped
}
},
'fedimint': {
state: PackageState.Running,
'static-files': {
license: 'MIT',
instructions: 'Federated Bitcoin mint',
icon: '/assets/img/icon-fedimint.jpeg'
},
manifest: {
id: 'fedimint',
title: 'Fedimint',
version: '0.3.0',
description: {
short: 'Federated Bitcoin minting service',
long: 'Fedimint is a federated Bitcoin mint that enables private, scalable Bitcoin transactions through a federation of guardians.'
},
'release-notes': 'Initial release',
license: 'MIT',
'wrapper-repo': 'https://github.com/fedimint/fedimint',
'upstream-repo': 'https://github.com/fedimint/fedimint',
'support-site': 'https://github.com/fedimint/fedimint/issues',
'marketing-site': 'https://fedimint.org',
'donation-url': null
},
installed: {
'current-dependents': {},
'current-dependencies': {},
'last-backup': null,
'interface-addresses': {
main: {
'tor-address': 'fedimint.onion',
'lan-address': 'http://localhost:8173'
}
},
status: ServiceStatus.Running
}
},
'morphos-server': {
state: PackageState.Running,
'static-files': {
license: 'MIT',
instructions: 'MorphOS server application',
icon: '/assets/img/morphos.png'
},
manifest: {
id: 'morphos-server',
title: 'MorphOS Server',
version: '1.0.0',
description: {
short: 'MorphOS server platform',
long: 'MorphOS Server provides a flexible server platform for various applications and services.'
},
'release-notes': 'Initial release',
license: 'MIT',
'wrapper-repo': 'https://github.com/morphos/morphos',
'upstream-repo': 'https://github.com/morphos/morphos',
'support-site': 'https://github.com/morphos/morphos/issues',
'marketing-site': 'https://morphos.io',
'donation-url': null
},
installed: {
'current-dependents': {},
'current-dependencies': {},
'last-backup': null,
'interface-addresses': {
main: {
'tor-address': 'morphos.onion',
'lan-address': 'http://localhost:8081'
}
},
status: ServiceStatus.Running
}
},
'lightning-stack': {
state: PackageState.Running,
'static-files': {
license: 'MIT',
instructions: 'Lightning Network stack',
icon: '/assets/img/app-icons/lightning-stack.png'
},
manifest: {
id: 'lightning-stack',
title: 'Lightning Stack',
version: '0.12.0',
description: {
short: 'Complete Lightning Network implementation',
long: 'Lightning Stack provides a complete Lightning Network node implementation with LND, CLN, and supporting services for fast Bitcoin transactions.'
},
'release-notes': 'Initial release',
license: 'MIT',
'wrapper-repo': 'https://github.com/Start9Labs/lnd-startos',
'upstream-repo': 'https://github.com/lightningnetwork/lnd',
'support-site': 'https://github.com/lightningnetwork/lnd/issues',
'marketing-site': 'https://lightning.network',
'donation-url': null
},
installed: {
'current-dependents': {},
'current-dependencies': {},
'last-backup': null,
'interface-addresses': {
main: {
'tor-address': 'lightning.onion',
'lan-address': 'http://localhost:9735'
}
},
status: ServiceStatus.Running
}
},
'mempool': {
state: PackageState.Running,
'static-files': {
license: 'AGPL-3.0',
instructions: 'Bitcoin mempool explorer',
icon: '/assets/img/app-icons/mempool.png'
},
manifest: {
id: 'mempool',
title: 'Mempool',
version: '2.5.0',
description: {
short: 'Bitcoin mempool and blockchain explorer',
long: 'Mempool is an open-source Bitcoin mempool and blockchain explorer. View transactions, blocks, and network statistics in real-time.'
},
'release-notes': 'Initial release',
license: 'AGPL-3.0',
'wrapper-repo': 'https://github.com/Start9Labs/mempool-startos',
'upstream-repo': 'https://github.com/mempool/mempool',
'support-site': 'https://github.com/mempool/mempool/issues',
'marketing-site': 'https://mempool.space',
'donation-url': null
},
installed: {
'current-dependents': {},
'current-dependencies': {},
'last-backup': null,
'interface-addresses': {
main: {
'tor-address': 'mempool.onion',
'lan-address': 'http://localhost:4080'
}
},
status: ServiceStatus.Running
}
},
'ollama': {
state: PackageState.Running,
'static-files': {
license: 'MIT',
instructions: 'Local AI model runner',
icon: '/assets/img/ollama.webp'
},
manifest: {
id: 'ollama',
title: 'Ollama',
version: '0.1.0',
description: {
short: 'Run large language models locally',
long: 'Ollama allows you to run large language models locally on your Neode server. Download and run models like Llama, Mistral, and more without cloud dependencies.'
},
'release-notes': 'Initial release',
license: 'MIT',
'wrapper-repo': 'https://github.com/ollama/ollama',
'upstream-repo': 'https://github.com/ollama/ollama',
'support-site': 'https://github.com/ollama/ollama/issues',
'marketing-site': 'https://ollama.ai',
'donation-url': null
},
installed: {
'current-dependents': {},
'current-dependencies': {},
'last-backup': null,
'interface-addresses': {
main: {
'tor-address': 'ollama.onion',
'lan-address': 'http://localhost:11434'
}
},
status: ServiceStatus.Running
}
},
'searxng': {
state: PackageState.Running,
'static-files': {
license: 'AGPL-3.0',
instructions: 'Privacy-respecting search engine',
icon: '/assets/img/app-icons/searxng.png'
},
manifest: {
id: 'searxng',
title: 'SearXNG',
version: '2024.1.0',
description: {
short: 'Privacy-respecting metasearch engine',
long: 'SearXNG is a privacy-respecting, hackable metasearch engine. Aggregate results from multiple search engines without tracking or ads.'
},
'release-notes': 'Initial release',
license: 'AGPL-3.0',
'wrapper-repo': 'https://github.com/searxng/searxng',
'upstream-repo': 'https://github.com/searxng/searxng',
'support-site': 'https://github.com/searxng/searxng/issues',
'marketing-site': 'https://searxng.org',
'donation-url': null
},
installed: {
'current-dependents': {},
'current-dependencies': {},
'last-backup': null,
'interface-addresses': {
main: {
'tor-address': 'searxng.onion',
'lan-address': 'http://localhost:8082'
}
},
status: ServiceStatus.Running
}
},
'onlyoffice': {
state: PackageState.Running,
'static-files': {
license: 'AGPL-3.0',
instructions: 'Office suite and document collaboration',
icon: '/assets/img/onlyoffice.webp'
},
manifest: {
id: 'onlyoffice',
title: 'OnlyOffice',
version: '7.5.0',
description: {
short: 'Office suite and document collaboration',
long: 'OnlyOffice is a secure office suite that enables real-time collaborative editing of documents, spreadsheets, and presentations. Self-hosted alternative to Google Workspace and Microsoft 365.'
},
'release-notes': 'Initial release',
license: 'AGPL-3.0',
'wrapper-repo': 'https://github.com/ONLYOFFICE/DocumentServer',
'upstream-repo': 'https://github.com/ONLYOFFICE/DocumentServer',
'support-site': 'https://github.com/ONLYOFFICE/DocumentServer/issues',
'marketing-site': 'https://www.onlyoffice.com',
'donation-url': null
},
installed: {
'current-dependents': {},
'current-dependencies': {},
'last-backup': null,
'interface-addresses': {
main: {
'tor-address': 'onlyoffice.onion',
'lan-address': 'http://localhost:8083'
}
},
status: ServiceStatus.Running
}
},
'penpot': {
state: PackageState.Running,
'static-files': {
license: 'MPL-2.0',
instructions: 'Design and prototyping platform',
icon: '/assets/img/penpot.webp'
},
manifest: {
id: 'penpot',
title: 'Penpot',
version: '2.0.0',
description: {
short: 'Open-source design and prototyping platform',
long: 'Penpot is an open-source design and prototyping platform for teams. Create designs, prototypes, and collaborate in real-time. Self-hosted alternative to Figma.'
},
'release-notes': 'Initial release',
license: 'MPL-2.0',
'wrapper-repo': 'https://github.com/penpot/penpot',
'upstream-repo': 'https://github.com/penpot/penpot',
'support-site': 'https://github.com/penpot/penpot/issues',
'marketing-site': 'https://penpot.app',
'donation-url': null
},
installed: {
'current-dependents': {},
'current-dependencies': {},
'last-backup': null,
'interface-addresses': {
main: {
'tor-address': 'penpot.onion',
'lan-address': 'http://localhost:9001'
}
},
status: ServiceStatus.Running
}
}
}

View File

@@ -0,0 +1,182 @@
// Utility to fetch app information from GitHub repositories
// Used to get icons, descriptions, and other metadata for dummy apps
export interface GitHubAppInfo {
icon?: string
description?: string
readme?: string
homepage?: string
}
/**
* Fetch app information from GitHub repository
* @param repoUrl GitHub repository URL (e.g., https://github.com/start9labs/bitcoin)
* @param appId App ID to help find the correct repository
*/
export async function fetchGitHubAppInfo(repoUrl: string, appId: string): Promise<GitHubAppInfo> {
try {
// Extract owner and repo from URL
const match = repoUrl.match(/github\.com\/([^\/]+)\/([^\/]+)/)
if (!match) {
console.warn(`[GitHub] Invalid repo URL: ${repoUrl}`)
return {}
}
const [, owner, repo] = match
// Try to find Start9 wrapper repo first (e.g., bitcoin-startos)
const start9RepoName = `${appId}-startos`
let targetOwner = owner
let targetRepo = repo
// If the repo URL doesn't match the expected pattern, try Start9Labs
if (repo && !repo.includes('startos') && !repo.includes('start9')) {
// Try Start9Labs wrapper repo
try {
const start9RepoUrl = `https://api.github.com/repos/Start9Labs/${start9RepoName}`
const start9Response = await fetch(start9RepoUrl)
if (start9Response.ok) {
targetOwner = 'Start9Labs'
targetRepo = start9RepoName
}
} catch (e) {
// Fall back to original repo
}
}
// Fetch repository info
const repoApiUrl = `https://api.github.com/repos/${targetOwner}/${targetRepo}`
const repoResponse = await fetch(repoApiUrl)
if (!repoResponse.ok) {
console.warn(`[GitHub] Failed to fetch repo ${targetOwner}/${targetRepo}: ${repoResponse.status}`)
return {}
}
const repoData = await repoResponse.json()
// Fetch README
let readme = ''
try {
const readmeResponse = await fetch(`https://api.github.com/repos/${targetOwner}/${targetRepo}/readme`)
if (readmeResponse.ok) {
const readmeData = await readmeResponse.json()
readme = atob(readmeData.content) // Base64 decode
}
} catch (e) {
console.warn(`[GitHub] Failed to fetch README for ${targetOwner}/${targetRepo}`)
}
// Try to find icon in repository
// Common locations: icon.png, icon.svg, assets/icon.png, etc.
let icon: string | undefined
const iconPaths = [
'icon.png',
'icon.svg',
'assets/icon.png',
'assets/icon.svg',
'icon/icon.png',
'icon/icon.svg'
]
for (const iconPath of iconPaths) {
try {
const iconResponse = await fetch(`https://api.github.com/repos/${targetOwner}/${targetRepo}/contents/${iconPath}`)
if (iconResponse.ok) {
const iconData = await iconResponse.json()
if (iconData.download_url) {
icon = iconData.download_url
break
}
}
} catch (e) {
// Try next path
}
}
// If no icon found, try to get from releases/assets
if (!icon) {
try {
const releasesResponse = await fetch(`https://api.github.com/repos/${targetOwner}/${targetRepo}/releases/latest`)
if (releasesResponse.ok) {
const releasesData = await releasesResponse.json()
const asset = releasesData.assets?.find((a: any) =>
a.name.includes('icon') || a.name.includes('logo')
)
if (asset) {
icon = asset.browser_download_url
}
}
} catch (e) {
// No icon from releases
}
}
// If still no icon, try raw GitHub content URLs for common icon names
if (!icon) {
const rawIconPaths = [
`https://raw.githubusercontent.com/${targetOwner}/${targetRepo}/main/icon.png`,
`https://raw.githubusercontent.com/${targetOwner}/${targetRepo}/main/icon.svg`,
`https://raw.githubusercontent.com/${targetOwner}/${targetRepo}/master/icon.png`,
`https://raw.githubusercontent.com/${targetOwner}/${targetRepo}/master/icon.svg`,
`https://raw.githubusercontent.com/${targetOwner}/${targetRepo}/main/assets/icon.png`,
`https://raw.githubusercontent.com/${targetOwner}/${targetRepo}/main/assets/icon.svg`,
]
// Test each URL
for (const iconUrl of rawIconPaths) {
try {
const testResponse = await fetch(iconUrl, { method: 'HEAD' })
if (testResponse.ok) {
icon = iconUrl
break
}
} catch (e) {
// Try next URL
}
}
}
return {
icon,
description: repoData.description || '',
readme,
homepage: repoData.homepage || repoData.html_url
}
} catch (error) {
console.error(`[GitHub] Error fetching app info for ${repoUrl}:`, error)
return {}
}
}
/**
* Batch fetch app info for multiple apps
*/
export async function fetchMultipleAppInfo(
apps: Array<{ id: string; 'wrapper-repo': string }>
): Promise<Record<string, GitHubAppInfo>> {
const results: Record<string, GitHubAppInfo> = {}
// Fetch in parallel with rate limiting (max 5 concurrent)
const batchSize = 5
for (let i = 0; i < apps.length; i += batchSize) {
const batch = apps.slice(i, i + batchSize)
const batchPromises = batch.map(async (app) => {
const info = await fetchGitHubAppInfo(app['wrapper-repo'], app.id)
return { id: app.id, info }
})
const batchResults = await Promise.all(batchPromises)
batchResults.forEach(({ id, info }) => {
results[id] = info
})
// Rate limit: wait 1 second between batches
if (i + batchSize < apps.length) {
await new Promise(resolve => setTimeout(resolve, 1000))
}
}
return results
}