0.1.0:3 - Show Public Key layout + /api/endpoints service-discovery

- showPublicKey now uses result.group: install command and raw key are each their own one-click copy box; description is brief
- /api/endpoints returns stable shape { vllm, parakeet, magpie } with base_url + model + ready, for other LAN services to consume without hardcoding Spark IPs
- health.py: parakeet/magpie now also expose base_url
- README: documented /api/endpoints shape
This commit is contained in:
Grant
2026-05-12 10:52:57 -05:00
parent 51804b2e5e
commit 2ba3da55b1
5 changed files with 121 additions and 36 deletions
+53 -27
View File
@@ -44,39 +44,65 @@ export const showPublicKey = sdk.Action.withoutInput(
hosts.push({ user: cfg.spark2_user, host: cfg.spark2_host })
}
let message: string
if (hosts.length > 0) {
const sshLines = hosts
.map(
(h) =>
`ssh ${h.user}@${h.host} "mkdir -p ~/.ssh && echo '$KEY' >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"`,
)
.join('\n')
const oneLiner = `KEY='${key}'\n${sshLines}`
message =
'Paste this block into any machine that already has SSH access to your Sparks (your laptop or one of the Sparks itself). It grants this Spark Control service permission to log in.\n\n' +
oneLiner +
'\n\nYou will be prompted for the SSH password of each Spark once. After both commands succeed, run "Test Connection" or open the Web Interface to verify.'
} else {
message =
'Run the "Configure Sparks" action first, then come back to this one — once your Spark hostnames are saved, this message will include a ready-to-paste install command.\n\nFor reference, the raw public key is:\n\n' +
key
if (hosts.length === 0) {
// Not yet configured — show just the raw key with instructions to come back.
return {
version: '1' as const,
title: 'SSH Public Key',
message:
'Run the "Configure Sparks" action first to enter your Spark hostnames. Once that\'s saved, re-run this action and it will produce a ready-to-paste install command for granting access.',
result: {
type: 'single' as const,
name: 'Public Key',
description:
'The bare ed25519 public key line. You can also wait until Configure Sparks is filled in to get a complete install command.',
value: key,
masked: false,
copyable: true,
qr: false,
},
}
}
const sshLines = hosts
.map(
(h) =>
`ssh ${h.user}@${h.host} "mkdir -p ~/.ssh && echo '$KEY' >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"`,
)
.join('\n')
const oneLiner = `KEY='${key}'\n${sshLines}`
return {
version: '1' as const,
title: 'SSH Public Key',
message,
message:
'Run the command below on any machine that already has SSH access to your Sparks (typically your laptop). You will be prompted for the SSH password of each Spark once. After it completes, open the Web Interface to verify.',
result: {
type: 'single' as const,
name: 'Raw Public Key',
description:
'The bare public key line. Copy the full message above for the ready-to-paste install command.',
value: key,
masked: false,
copyable: true,
qr: false,
type: 'group' as const,
name: 'Install command and raw key',
description: null,
value: [
{
type: 'single' as const,
name: 'Install command',
description:
'Copy this entire block and paste it into a terminal on your laptop. It will append the key to ~/.ssh/authorized_keys on each Spark.',
value: oneLiner,
masked: false,
copyable: true,
qr: false,
},
{
type: 'single' as const,
name: 'Raw public key',
description:
'Just the public key on its own, in case you prefer to install it manually.',
value: key,
masked: false,
copyable: true,
qr: false,
},
],
},
}
},
+2 -2
View File
@@ -1,10 +1,10 @@
import { VersionInfo, IMPOSSIBLE } from '@start9labs/start-sdk'
export const v0_1_0 = VersionInfo.of({
version: '0.1.0:2',
version: '0.1.0:3',
releaseNotes: {
en_US:
'Fully generic SSH user fields (no suggested default); generic host placeholders in Configure Sparks; Show Public Key emits a ready-to-paste install command using your configured hostnames; dashboard shows the OpenAI-compatible base URL + current model ID with one-click copy and a curl example.',
'Show Public Key: install command moved to its own copy box (cleaner than mixing it into the description). New /api/endpoints route for service discovery — other services on your LAN can GET it to learn vLLM/Parakeet/Magpie base URLs and current model without hardcoding Spark IPs.',
},
migrations: {
up: async ({ effects }) => {},