wip: vscode extension
This commit is contained in:
@@ -12,6 +12,7 @@ import { Bus } from "../../bus"
|
||||
import { Log } from "../../util/log"
|
||||
import { FileWatcher } from "../../file/watch"
|
||||
import { Mode } from "../../session/mode"
|
||||
import { Ide } from "../../ide"
|
||||
|
||||
export const TuiCommand = cmd({
|
||||
command: "$0 [project]",
|
||||
@@ -116,6 +117,16 @@ export const TuiCommand = cmd({
|
||||
})
|
||||
.catch(() => {})
|
||||
})()
|
||||
;(async () => {
|
||||
if (Ide.alreadyInstalled()) return
|
||||
const ide = await Ide.ide()
|
||||
if (ide === "unknown") return
|
||||
await Ide.install(ide)
|
||||
.then(() => {
|
||||
Bus.publish(Ide.Event.Installed, { ide })
|
||||
})
|
||||
.catch(() => {})
|
||||
})()
|
||||
|
||||
await proc.exited
|
||||
server.stop()
|
||||
|
||||
74
packages/opencode/src/ide/index.ts
Normal file
74
packages/opencode/src/ide/index.ts
Normal file
@@ -0,0 +1,74 @@
|
||||
import { $ } from "bun"
|
||||
import { z } from "zod"
|
||||
import { NamedError } from "../util/error"
|
||||
import { Log } from "../util/log"
|
||||
import { Bus } from "../bus"
|
||||
|
||||
const SUPPORTED_IDES = ["Windsurf", "Visual Studio Code", "Cursor", "VSCodium"] as const
|
||||
|
||||
export namespace Ide {
|
||||
const log = Log.create({ service: "ide" })
|
||||
|
||||
export const Event = {
|
||||
Installed: Bus.event(
|
||||
"ide.installed",
|
||||
z.object({
|
||||
ide: z.string(),
|
||||
}),
|
||||
),
|
||||
}
|
||||
|
||||
export type Ide = Awaited<ReturnType<typeof ide>>
|
||||
|
||||
export const AlreadyInstalledError = NamedError.create("AlreadyInstalledError", z.object({}))
|
||||
|
||||
export const InstallFailedError = NamedError.create(
|
||||
"InstallFailedError",
|
||||
z.object({
|
||||
stderr: z.string(),
|
||||
}),
|
||||
)
|
||||
|
||||
export async function ide() {
|
||||
if (process.env["TERM_PROGRAM"] === "vscode") {
|
||||
const v = process.env["GIT_ASKPASS"]
|
||||
for (const ide of SUPPORTED_IDES) {
|
||||
if (v?.includes(ide)) return ide
|
||||
}
|
||||
}
|
||||
return "unknown"
|
||||
}
|
||||
|
||||
export function alreadyInstalled() {
|
||||
return process.env["OPENCODE_CALLER"] === "vscode"
|
||||
}
|
||||
|
||||
export async function install(ide: Ide) {
|
||||
const cmd = (() => {
|
||||
switch (ide) {
|
||||
case "Windsurf":
|
||||
return $`windsurf --install-extension sst-dev.opencode`
|
||||
case "Visual Studio Code":
|
||||
return $`code --install-extension sst-dev.opencode`
|
||||
case "Cursor":
|
||||
return $`cursor --install-extension sst-dev.opencode`
|
||||
case "VSCodium":
|
||||
return $`codium --install-extension sst-dev.opencode`
|
||||
default:
|
||||
throw new Error(`Unknown IDE: ${ide}`)
|
||||
}
|
||||
})()
|
||||
// TODO: check OPENCODE_CALLER
|
||||
const result = await cmd.quiet().throws(false)
|
||||
log.info("installed", {
|
||||
ide,
|
||||
stdout: result.stdout.toString(),
|
||||
stderr: result.stderr.toString(),
|
||||
})
|
||||
if (result.exitCode !== 0)
|
||||
throw new InstallFailedError({
|
||||
stderr: result.stderr.toString("utf8"),
|
||||
})
|
||||
if (result.stdout.toString().includes("already installed")) throw new AlreadyInstalledError({})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user