1
0
Эх сурвалжийг харах

fix(cli): support service autostart setting

Dax Raad 1 сар өмнө
parent
commit
0f9719a7b5

+ 35 - 1
packages/cli/src/services/daemon.ts

@@ -36,10 +36,11 @@ const ServiceConfig = Schema.Struct({
   hostname: Schema.optional(Schema.String),
   port: Schema.optional(Schema.Int.check(Schema.isGreaterThanOrEqualTo(1), Schema.isLessThanOrEqualTo(65_535))),
   password: Schema.optional(Schema.String),
+  autostart: Schema.optional(Schema.Boolean),
 })
 export type ServiceConfig = typeof ServiceConfig.Type
 
-const serviceConfigKeys = ["hostname", "port", "password"] as const
+const serviceConfigKeys = ["hostname", "port", "password", "autostart"] as const
 type ServiceConfigKey = (typeof serviceConfigKeys)[number]
 
 function serviceConfigKey(key: string): ServiceConfigKey {
@@ -102,6 +103,10 @@ export const layer = Layer.effect(
         case "password": {
           return yield* password()
         }
+        case "autostart": {
+          const autostart = (yield* config()).autostart
+          return autostart === undefined ? "" : String(autostart)
+        }
       }
     })
 
@@ -124,6 +129,11 @@ export const layer = Layer.effect(
           yield* password(value)
           return
         }
+        case "autostart": {
+          if (value !== "true" && value !== "false") throw new Error("Autostart must be true or false")
+          yield* writeConfig({ ...(yield* config()), autostart: value === "true" })
+          return
+        }
       }
     })
 
@@ -147,6 +157,11 @@ export const layer = Layer.effect(
           yield* writeConfig(next)
           return
         }
+        case "autostart": {
+          const { autostart: _autostart, ...next } = yield* config()
+          yield* writeConfig(next)
+          return
+        }
       }
     })
 
@@ -166,6 +181,16 @@ export const layer = Layer.effect(
       return yield* Effect.fail(new Error("Registered server is not healthy"))
     })
 
+    const remoteTransport = Effect.fn("cli.daemon.remoteTransport")(function* (input: ServiceConfig) {
+      const url = serviceURL(input)
+      const headers = ServerAuth.headers({ password: input.password })
+      const response = yield* Effect.tryPromise(() =>
+        createOpencodeClient({ baseUrl: url, headers }).v2.health.get({ signal: AbortSignal.timeout(2_000) }),
+      )
+      if (response.data?.healthy === true) return { url, headers }
+      return yield* Effect.fail(new Error(`Server is not healthy: ${url}`))
+    })
+
     const compatible = Effect.fnUntraced(function* () {
       const info = yield* healthy()
       if (info.version === InstallationVersion) return info
@@ -230,6 +255,8 @@ export const layer = Layer.effect(
     })
 
     const transport = Effect.fn("cli.daemon.transport")(function* () {
+      const current = yield* config()
+      if (current.autostart === false) return yield* remoteTransport(current)
       return { url: yield* start(), headers: ServerAuth.headers({ password: yield* password() }) }
     })
 
@@ -286,4 +313,11 @@ export const layer = Layer.effect(
 
 export const defaultLayer = layer
 
+function serviceURL(config: ServiceConfig) {
+  const hostname = config.hostname ?? "127.0.0.1"
+  const result = new URL(`http://${hostname.includes(":") && !hostname.startsWith("[") ? `[${hostname}]` : hostname}`)
+  result.port = String(config.port ?? 4096)
+  return result.toString()
+}
+
 export * as Daemon from "./daemon"