fix(cli): show background server startup status
This commit is contained in:
@@ -18,6 +18,12 @@ export default Runtime.handler(Commands, (input) =>
|
|||||||
const server = yield* Server.resolve({
|
const server = yield* Server.resolve({
|
||||||
server: Option.getOrUndefined(input.server),
|
server: Option.getOrUndefined(input.server),
|
||||||
standalone: input.standalone,
|
standalone: input.standalone,
|
||||||
|
onStart: (reason) =>
|
||||||
|
process.stderr.write(
|
||||||
|
reason === "version-mismatch"
|
||||||
|
? "Restarting background server (version mismatch)...\n"
|
||||||
|
: "Starting background server...\n",
|
||||||
|
),
|
||||||
})
|
})
|
||||||
const config = TuiConfig.resolve({}, { terminalSuspend: false })
|
const config = TuiConfig.resolve({}, { terminalSuspend: false })
|
||||||
let disposeSlots: (() => void) | undefined
|
let disposeSlots: (() => void) | undefined
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ export type Args = {
|
|||||||
readonly server?: string
|
readonly server?: string
|
||||||
readonly standalone?: boolean
|
readonly standalone?: boolean
|
||||||
readonly mismatch?: "replace" | "ignore" | "error"
|
readonly mismatch?: "replace" | "ignore" | "error"
|
||||||
|
readonly onStart?: Service.StartOptions["onStart"]
|
||||||
}
|
}
|
||||||
|
|
||||||
export type Resolved = {
|
export type Resolved = {
|
||||||
@@ -46,7 +47,7 @@ export const resolve = Effect.fn("cli.server.resolve")(function* (args: Args) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const options = yield* ServiceConfig.options()
|
const options = yield* ServiceConfig.options()
|
||||||
const endpoint = yield* resolveManaged(options, args.mismatch ?? "replace")
|
const endpoint = yield* resolveManaged({ ...options, onStart: args.onStart }, args.mismatch ?? "replace")
|
||||||
const reconnectOptions = { ...options, version: undefined }
|
const reconnectOptions = { ...options, version: undefined }
|
||||||
return {
|
return {
|
||||||
endpoint,
|
endpoint,
|
||||||
@@ -70,7 +71,7 @@ export const resolve = Effect.fn("cli.server.resolve")(function* (args: Args) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
const resolveManaged = Effect.fnUntraced(function* (
|
const resolveManaged = Effect.fnUntraced(function* (
|
||||||
options: Service.Options,
|
options: Service.StartOptions,
|
||||||
mismatch: NonNullable<Args["mismatch"]>,
|
mismatch: NonNullable<Args["mismatch"]>,
|
||||||
) {
|
) {
|
||||||
if (mismatch === "replace") return yield* Service.start(options)
|
if (mismatch === "replace") return yield* Service.start(options)
|
||||||
|
|||||||
@@ -32,6 +32,12 @@ export type Options = {
|
|||||||
readonly command?: ReadonlyArray<string>
|
readonly command?: ReadonlyArray<string>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type StartReason = "missing" | "version-mismatch"
|
||||||
|
|
||||||
|
export type StartOptions = Options & {
|
||||||
|
readonly onStart?: (reason: StartReason) => void
|
||||||
|
}
|
||||||
|
|
||||||
// Read-only lookup: registration file plus health check and version gate.
|
// Read-only lookup: registration file plus health check and version gate.
|
||||||
// Never spawns; escalation to start() is the caller's policy.
|
// Never spawns; escalation to start() is the caller's policy.
|
||||||
export const discover = Effect.fn("service.discover")(function* (options: Options = {}) {
|
export const discover = Effect.fn("service.discover")(function* (options: Options = {}) {
|
||||||
@@ -47,10 +53,11 @@ const discoverLocal = Effect.fnUntraced(function* (options: Options) {
|
|||||||
|
|
||||||
// Idempotent ensure-running: reuses a healthy compatible server, replaces a
|
// Idempotent ensure-running: reuses a healthy compatible server, replaces a
|
||||||
// version-mismatched one, and otherwise spawns the service command detached.
|
// version-mismatched one, and otherwise spawns the service command detached.
|
||||||
export const start = Effect.fn("service.start")(function* (options: Options = {}) {
|
export const start = Effect.fn("service.start")(function* (options: StartOptions = {}) {
|
||||||
const compatible = yield* discover(options)
|
const compatible = yield* discover(options)
|
||||||
if (compatible !== undefined) return compatible
|
if (compatible !== undefined) return compatible
|
||||||
const mismatched = yield* find(options)
|
const mismatched = yield* find(options)
|
||||||
|
yield* Effect.sync(() => options.onStart?.(mismatched === undefined ? "missing" : "version-mismatch"))
|
||||||
if (mismatched !== undefined) yield* kill(mismatched.info, options).pipe(Effect.ignore)
|
if (mismatched !== undefined) yield* kill(mismatched.info, options).pipe(Effect.ignore)
|
||||||
|
|
||||||
const [command, ...args] = options.command ?? ["opencode", "serve", "--service"]
|
const [command, ...args] = options.command ?? ["opencode", "serve", "--service"]
|
||||||
|
|||||||
Reference in New Issue
Block a user