mirror of
https://github.com/anomalyco/opencode.git
synced 2026-07-17 12:56:41 +02:00
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e30fba0d3c | |||
| 7fbb2ca9a6 | |||
| 230d0a1510 | |||
| 46ff2c0ae0 |
@@ -3,3 +3,5 @@ node_modules
|
||||
.opencode
|
||||
.sst
|
||||
.env
|
||||
.idea
|
||||
.vscode
|
||||
|
||||
@@ -64,7 +64,7 @@ for (const [os, arch] of targets) {
|
||||
|
||||
await $`mkdir -p ./dist/${pkg.name}`
|
||||
await $`cp -r ./bin ./dist/${pkg.name}/bin`
|
||||
await $`cp ./script/postinstall.js ./dist/${pkg.name}/postinstall.js`
|
||||
await $`cp ./script/postinstall.mjs ./dist/${pkg.name}/postinstall.mjs`
|
||||
await Bun.file(`./dist/${pkg.name}/package.json`).write(
|
||||
JSON.stringify(
|
||||
{
|
||||
@@ -73,7 +73,7 @@ await Bun.file(`./dist/${pkg.name}/package.json`).write(
|
||||
[pkg.name]: `./bin/${pkg.name}`,
|
||||
},
|
||||
scripts: {
|
||||
postinstall: "node ./postinstall.js",
|
||||
postinstall: "node ./postinstall.mjs",
|
||||
},
|
||||
version,
|
||||
optionalDependencies,
|
||||
|
||||
@@ -115,9 +115,6 @@ export const RunCommand = {
|
||||
})
|
||||
|
||||
const { providerID, modelID } = await Provider.defaultModel()
|
||||
setTimeout(() => {
|
||||
Session.abort(session.id)
|
||||
}, 8000)
|
||||
await Session.chat({
|
||||
sessionID: session.id,
|
||||
providerID,
|
||||
|
||||
@@ -122,7 +122,7 @@ export const UpgradeCommand = {
|
||||
UI.empty()
|
||||
UI.println(UI.logo(" "))
|
||||
UI.empty()
|
||||
prompts.intro("upgrade")
|
||||
prompts.intro("Upgrade")
|
||||
|
||||
if (!process.execPath.includes(path.join(".opencode", "bin")) && false) {
|
||||
prompts.log.error(
|
||||
@@ -132,10 +132,16 @@ export const UpgradeCommand = {
|
||||
return
|
||||
}
|
||||
|
||||
const release = args.target ? await specific(args.target) : await latest()
|
||||
const target = release.tag_name
|
||||
const release = args.target
|
||||
? await specific(args.target).catch(() => {})
|
||||
: await latest().catch(() => {})
|
||||
if (!release) {
|
||||
prompts.log.error("Failed to fetch release information")
|
||||
prompts.outro("Done")
|
||||
return
|
||||
}
|
||||
|
||||
prompts.log.info(`Upgrade ${VERSION} → ${target}`)
|
||||
const target = release.tag_name
|
||||
|
||||
if (VERSION !== "dev" && compare(VERSION, target) >= 0) {
|
||||
prompts.log.success(`Already up to date`)
|
||||
@@ -143,6 +149,8 @@ export const UpgradeCommand = {
|
||||
return
|
||||
}
|
||||
|
||||
prompts.log.info(`From ${VERSION} → ${target}`)
|
||||
|
||||
const name = asset()
|
||||
const found = release.assets.find((a) => a.name === name)
|
||||
|
||||
@@ -155,30 +163,30 @@ export const UpgradeCommand = {
|
||||
const spinner = prompts.spinner()
|
||||
spinner.start("Downloading update...")
|
||||
|
||||
let downloadPath: string
|
||||
try {
|
||||
downloadPath = await download(found.browser_download_url)
|
||||
spinner.stop("Download complete")
|
||||
} catch (downloadError) {
|
||||
const downloadPath = await download(found.browser_download_url).catch(
|
||||
() => {},
|
||||
)
|
||||
if (!downloadPath) {
|
||||
spinner.stop("Download failed")
|
||||
prompts.log.error(
|
||||
`Download failed: ${downloadError instanceof Error ? downloadError.message : String(downloadError)}`,
|
||||
)
|
||||
prompts.log.error("Download failed")
|
||||
prompts.outro("Done")
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
await fs.rename(downloadPath, process.execPath)
|
||||
prompts.log.success(`Successfully upgraded to ${target}`)
|
||||
} catch (installError) {
|
||||
prompts.log.error(
|
||||
`Install failed: ${installError instanceof Error ? installError.message : String(installError)}`,
|
||||
)
|
||||
// Clean up downloaded file
|
||||
spinner.stop("Download complete")
|
||||
|
||||
const renamed = await fs
|
||||
.rename(downloadPath, process.execPath)
|
||||
.catch(() => {})
|
||||
|
||||
if (renamed === undefined) {
|
||||
prompts.log.error("Install failed")
|
||||
await fs.unlink(downloadPath).catch(() => {})
|
||||
prompts.outro("Done")
|
||||
return
|
||||
}
|
||||
|
||||
prompts.log.success(`Successfully upgraded to ${target}`)
|
||||
prompts.outro("Done")
|
||||
},
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import { LANGUAGE_EXTENSIONS } from "./language"
|
||||
import { Bus } from "../bus"
|
||||
import z from "zod"
|
||||
import type { LSPServer } from "./server"
|
||||
import { NamedError } from "../util/error"
|
||||
|
||||
export namespace LSPClient {
|
||||
const log = Log.create({ service: "lsp.client" })
|
||||
@@ -19,6 +20,13 @@ export namespace LSPClient {
|
||||
|
||||
export type Diagnostic = VSCodeDiagnostic
|
||||
|
||||
export const InitializeError = NamedError.create(
|
||||
"LSPInitializeError",
|
||||
z.object({
|
||||
serverID: z.string(),
|
||||
}),
|
||||
)
|
||||
|
||||
export const Event = {
|
||||
Diagnostics: Bus.event(
|
||||
"lsp.client.diagnostics",
|
||||
@@ -52,32 +60,40 @@ export namespace LSPClient {
|
||||
})
|
||||
connection.listen()
|
||||
|
||||
await connection.sendRequest("initialize", {
|
||||
processId: server.process.pid,
|
||||
workspaceFolders: [
|
||||
{
|
||||
name: "workspace",
|
||||
uri: "file://" + app.path.cwd,
|
||||
},
|
||||
],
|
||||
initializationOptions: {
|
||||
...server.initialization,
|
||||
},
|
||||
capabilities: {
|
||||
workspace: {
|
||||
configuration: true,
|
||||
},
|
||||
textDocument: {
|
||||
synchronization: {
|
||||
didOpen: true,
|
||||
didChange: true,
|
||||
log.info("sending initialize", { id: serverID })
|
||||
await Promise.race([
|
||||
connection.sendRequest("initialize", {
|
||||
processId: server.process.pid,
|
||||
workspaceFolders: [
|
||||
{
|
||||
name: "workspace",
|
||||
uri: "file://" + app.path.cwd,
|
||||
},
|
||||
publishDiagnostics: {
|
||||
versionSupport: true,
|
||||
],
|
||||
initializationOptions: {
|
||||
...server.initialization,
|
||||
},
|
||||
capabilities: {
|
||||
workspace: {
|
||||
configuration: true,
|
||||
},
|
||||
textDocument: {
|
||||
synchronization: {
|
||||
didOpen: true,
|
||||
didChange: true,
|
||||
},
|
||||
publishDiagnostics: {
|
||||
versionSupport: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
}),
|
||||
new Promise((_, reject) => {
|
||||
setTimeout(() => {
|
||||
reject(new InitializeError({ serverID }))
|
||||
}, 5_000)
|
||||
}),
|
||||
])
|
||||
await connection.sendNotification("initialized", {})
|
||||
log.info("initialized")
|
||||
|
||||
|
||||
@@ -12,9 +12,10 @@ export namespace LSP {
|
||||
async () => {
|
||||
log.info("initializing")
|
||||
const clients = new Map<string, LSPClient.Info>()
|
||||
|
||||
const skip = new Set<string>()
|
||||
return {
|
||||
clients,
|
||||
skip,
|
||||
}
|
||||
},
|
||||
async (state) => {
|
||||
@@ -31,11 +32,19 @@ export namespace LSP {
|
||||
x.extensions.includes(extension),
|
||||
)
|
||||
for (const match of matches) {
|
||||
if (s.skip.has(match.id)) continue
|
||||
const existing = s.clients.get(match.id)
|
||||
if (existing) continue
|
||||
const handle = await match.spawn(App.info())
|
||||
if (!handle) continue
|
||||
const client = await LSPClient.create(match.id, handle)
|
||||
if (!handle) {
|
||||
s.skip.add(match.id)
|
||||
continue
|
||||
}
|
||||
const client = await LSPClient.create(match.id, handle).catch(() => {})
|
||||
if (!client) {
|
||||
s.skip.add(match.id)
|
||||
continue
|
||||
}
|
||||
s.clients.set(match.id, client)
|
||||
}
|
||||
if (waitForDiagnostics) {
|
||||
|
||||
@@ -82,7 +82,7 @@ export namespace Provider {
|
||||
>()
|
||||
const sdk = new Map<string, SDK>()
|
||||
|
||||
log.info("loading")
|
||||
log.info("init")
|
||||
|
||||
function mergeProvider(
|
||||
id: string,
|
||||
@@ -167,7 +167,7 @@ export namespace Provider {
|
||||
}
|
||||
|
||||
for (const providerID of Object.keys(providers)) {
|
||||
log.info("loaded", { providerID })
|
||||
log.info("found", { providerID })
|
||||
}
|
||||
|
||||
return {
|
||||
@@ -183,6 +183,9 @@ export namespace Provider {
|
||||
|
||||
async function getSDK(providerID: string) {
|
||||
return (async () => {
|
||||
using _ = log.time("getSDK", {
|
||||
providerID,
|
||||
})
|
||||
const s = await state()
|
||||
const existing = s.sdk.get(providerID)
|
||||
if (existing) return existing
|
||||
@@ -202,7 +205,7 @@ export namespace Provider {
|
||||
const s = await state()
|
||||
if (s.models.has(key)) return s.models.get(key)!
|
||||
|
||||
log.info("loading", {
|
||||
log.info("getModel", {
|
||||
providerID,
|
||||
modelID,
|
||||
})
|
||||
|
||||
@@ -41,8 +41,7 @@ export const ListTool = Tool.define({
|
||||
const files = []
|
||||
|
||||
for await (const file of glob.scan({ cwd: searchPath, dot: true })) {
|
||||
if (file.startsWith(".") || IGNORE_PATTERNS.some((p) => file.includes(p)))
|
||||
continue
|
||||
if (IGNORE_PATTERNS.some((p) => file.includes(p))) continue
|
||||
if (params.ignore?.some((pattern) => new Bun.Glob(pattern).match(file)))
|
||||
continue
|
||||
files.push(file)
|
||||
|
||||
@@ -83,6 +83,23 @@ export namespace Log {
|
||||
clone() {
|
||||
return Log.create({ ...tags })
|
||||
},
|
||||
time(message: string, extra?: Record<string, any>) {
|
||||
const now = Date.now()
|
||||
result.info(message, { status: "started", ...extra })
|
||||
function stop() {
|
||||
result.info(message, {
|
||||
status: "completed",
|
||||
duration: Date.now() - now,
|
||||
...extra,
|
||||
})
|
||||
}
|
||||
return {
|
||||
stop,
|
||||
[Symbol.dispose]() {
|
||||
stop()
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
return result
|
||||
|
||||
Reference in New Issue
Block a user