feat: complete upgrade-machinery removal — drop /global/upgrade endpoint, gut passive check
This commit is contained in:
@@ -1,52 +1,4 @@
|
|||||||
import { Flag } from "@opencode-ai/core/flag/flag"
|
// Neuron fork: self-update machinery has been lobotomized.
|
||||||
import { Installation } from "@/installation"
|
// The passive check is a no-op and the /global/upgrade server route is gone.
|
||||||
import { InstallationVersion } from "@opencode-ai/core/installation/version"
|
// Manual upgrades are impossible by design; rebuild from source instead.
|
||||||
import { GlobalBus } from "@/bus/global"
|
export async function upgrade() {}
|
||||||
|
|
||||||
export async function upgrade() {
|
|
||||||
// Neuron fork: the passive update check is disabled. Set
|
|
||||||
// OPENCODE_ALWAYS_NOTIFY_UPDATE=1 to re-enable release notifications.
|
|
||||||
if (!Flag.OPENCODE_ALWAYS_NOTIFY_UPDATE) return
|
|
||||||
const method = await Installation.method()
|
|
||||||
const latest = await Installation.latest(method).catch(() => {})
|
|
||||||
if (!latest) return
|
|
||||||
|
|
||||||
if (Flag.OPENCODE_ALWAYS_NOTIFY_UPDATE) {
|
|
||||||
GlobalBus.emit("event", {
|
|
||||||
directory: "global",
|
|
||||||
payload: {
|
|
||||||
type: Installation.Event.UpdateAvailable.type,
|
|
||||||
properties: { version: latest },
|
|
||||||
},
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (InstallationVersion === latest) return
|
|
||||||
|
|
||||||
const kind = Installation.getReleaseType(InstallationVersion, latest)
|
|
||||||
|
|
||||||
if (kind !== "patch") {
|
|
||||||
GlobalBus.emit("event", {
|
|
||||||
directory: "global",
|
|
||||||
payload: {
|
|
||||||
type: Installation.Event.UpdateAvailable.type,
|
|
||||||
properties: { version: latest },
|
|
||||||
},
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (method === "unknown") return
|
|
||||||
await Installation.upgrade(method, latest)
|
|
||||||
.then(() =>
|
|
||||||
GlobalBus.emit("event", {
|
|
||||||
directory: "global",
|
|
||||||
payload: {
|
|
||||||
type: Installation.Event.Updated.type,
|
|
||||||
properties: { version: latest },
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
.catch(() => {})
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -47,9 +47,6 @@ const GlobalEventSchema = Schema.Struct({
|
|||||||
]),
|
]),
|
||||||
}).annotate({ identifier: "GlobalEvent" })
|
}).annotate({ identifier: "GlobalEvent" })
|
||||||
|
|
||||||
export const GlobalUpgradeInput = Schema.Struct({
|
|
||||||
target: Schema.optional(Schema.String),
|
|
||||||
})
|
|
||||||
|
|
||||||
const GlobalUpgradeResult = Schema.Union([
|
const GlobalUpgradeResult = Schema.Union([
|
||||||
Schema.Struct({
|
Schema.Struct({
|
||||||
@@ -67,7 +64,6 @@ export const GlobalPaths = {
|
|||||||
event: "/global/event",
|
event: "/global/event",
|
||||||
config: "/global/config",
|
config: "/global/config",
|
||||||
dispose: "/global/dispose",
|
dispose: "/global/dispose",
|
||||||
upgrade: "/global/upgrade",
|
|
||||||
} as const
|
} as const
|
||||||
|
|
||||||
export const GlobalApi = HttpApi.make("global").add(
|
export const GlobalApi = HttpApi.make("global").add(
|
||||||
@@ -120,17 +116,6 @@ export const GlobalApi = HttpApi.make("global").add(
|
|||||||
description: "Clean up and dispose all Neuron instances, releasing all resources.",
|
description: "Clean up and dispose all Neuron instances, releasing all resources.",
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
HttpApiEndpoint.post("upgrade", GlobalPaths.upgrade, {
|
|
||||||
payload: [HttpApiSchema.NoContent, GlobalUpgradeInput],
|
|
||||||
success: described(GlobalUpgradeResult, "Upgrade result"),
|
|
||||||
error: HttpApiError.BadRequest,
|
|
||||||
}).annotateMerge(
|
|
||||||
OpenApi.annotations({
|
|
||||||
identifier: "global.upgrade",
|
|
||||||
summary: "Upgrade opencode",
|
|
||||||
description: "Upgrade opencode to the specified version or latest if not specified.",
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
.annotateMerge(OpenApi.annotations({ title: "global", description: "Global server routes." })),
|
.annotateMerge(OpenApi.annotations({ title: "global", description: "Global server routes." })),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import { HttpServerRequest, HttpServerResponse } from "effect/unstable/http"
|
|||||||
import { HttpApiBuilder } from "effect/unstable/httpapi"
|
import { HttpApiBuilder } from "effect/unstable/httpapi"
|
||||||
import * as Sse from "effect/unstable/encoding/Sse"
|
import * as Sse from "effect/unstable/encoding/Sse"
|
||||||
import { RootHttpApi } from "../api"
|
import { RootHttpApi } from "../api"
|
||||||
import { GlobalUpgradeInput } from "../groups/global"
|
|
||||||
|
|
||||||
function eventData(data: unknown): Sse.Event {
|
function eventData(data: unknown): Sse.Event {
|
||||||
return {
|
return {
|
||||||
@@ -94,63 +93,11 @@ export const globalHandlers = HttpApiBuilder.group(RootHttpApi, "global", (handl
|
|||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
|
|
||||||
const upgrade = Effect.fn("GlobalHttpApi.upgrade")(function* (ctx: { payload: typeof GlobalUpgradeInput.Type }) {
|
|
||||||
const method = yield* installation.method()
|
|
||||||
if (method === "unknown") {
|
|
||||||
return {
|
|
||||||
status: 400,
|
|
||||||
body: { success: false as const, error: "Unknown installation method" },
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const target = ctx.payload.target || (yield* installation.latest(method))
|
|
||||||
const result = yield* installation.upgrade(method, target).pipe(
|
|
||||||
Effect.as({ status: 200, body: { success: true as const, version: target } }),
|
|
||||||
Effect.catch((err) =>
|
|
||||||
Effect.succeed({
|
|
||||||
status: 500,
|
|
||||||
body: {
|
|
||||||
success: false as const,
|
|
||||||
error: err instanceof Error ? err.message : String(err),
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
if (!result.body.success) return result
|
|
||||||
GlobalBus.emit("event", {
|
|
||||||
directory: "global",
|
|
||||||
payload: {
|
|
||||||
type: Installation.Event.Updated.type,
|
|
||||||
properties: { version: target },
|
|
||||||
},
|
|
||||||
})
|
|
||||||
return result
|
|
||||||
})
|
|
||||||
|
|
||||||
const upgradeRaw = Effect.fn("GlobalHttpApi.upgradeRaw")(function* (ctx: {
|
|
||||||
request: HttpServerRequest.HttpServerRequest
|
|
||||||
}) {
|
|
||||||
const body = yield* Effect.orDie(ctx.request.text)
|
|
||||||
const json = parseBody(body)
|
|
||||||
if (json === undefined) {
|
|
||||||
return HttpServerResponse.jsonUnsafe({ success: false, error: "Invalid request body" }, { status: 400 })
|
|
||||||
}
|
|
||||||
const payload = yield* Schema.decodeUnknownEffect(GlobalUpgradeInput)(json).pipe(
|
|
||||||
Effect.map((payload) => ({ valid: true as const, payload })),
|
|
||||||
Effect.catch(() => Effect.succeed({ valid: false as const })),
|
|
||||||
)
|
|
||||||
if (!payload.valid) {
|
|
||||||
return HttpServerResponse.jsonUnsafe({ success: false, error: "Invalid request body" }, { status: 400 })
|
|
||||||
}
|
|
||||||
const result = yield* upgrade({ payload: payload.payload })
|
|
||||||
return HttpServerResponse.jsonUnsafe(result.body, { status: result.status })
|
|
||||||
})
|
|
||||||
|
|
||||||
return handlers
|
return handlers
|
||||||
.handle("health", health)
|
.handle("health", health)
|
||||||
.handleRaw("event", event)
|
.handleRaw("event", event)
|
||||||
.handle("configGet", configGet)
|
.handle("configGet", configGet)
|
||||||
.handle("configUpdate", configUpdate)
|
.handle("configUpdate", configUpdate)
|
||||||
.handle("dispose", dispose)
|
.handle("dispose", dispose)
|
||||||
.handleRaw("upgrade", upgradeRaw)
|
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user