mirror of
https://github.com/anomalyco/opencode.git
synced 2026-04-16 10:54:52 +00:00
Compare commits
1 Commits
kit/ns-pro
...
kit/fs-cli
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
042e63fdc3 |
@@ -33,7 +33,6 @@ import {
|
||||
|
||||
import { Log } from "../util/log"
|
||||
import { pathToFileURL } from "url"
|
||||
import { Filesystem } from "../util/filesystem"
|
||||
import { Hash } from "../util/hash"
|
||||
import { ACPSessionManager } from "./session"
|
||||
import type { ACPConfig } from "./types"
|
||||
@@ -48,7 +47,9 @@ import { Todo } from "@/session/todo"
|
||||
import { z } from "zod"
|
||||
import { LoadAPIKeyError } from "ai"
|
||||
import type { AssistantMessage, Event, OpencodeClient, SessionMessageResponse, ToolPart } from "@opencode-ai/sdk/v2"
|
||||
import { AppFileSystem } from "@opencode-ai/shared/filesystem"
|
||||
import { applyPatch } from "diff"
|
||||
import { Effect } from "effect"
|
||||
|
||||
type ModeOption = { id: string; name: string; description?: string }
|
||||
type ModelOption = { modelId: string; name: string }
|
||||
@@ -238,7 +239,13 @@ export namespace ACP {
|
||||
const metadata = permission.metadata || {}
|
||||
const filepath = typeof metadata["filepath"] === "string" ? metadata["filepath"] : ""
|
||||
const diff = typeof metadata["diff"] === "string" ? metadata["diff"] : ""
|
||||
const content = (await Filesystem.exists(filepath)) ? await Filesystem.readText(filepath) : ""
|
||||
const content = await AppRuntime.runPromise(
|
||||
AppFileSystem.Service.use((fs) =>
|
||||
fs
|
||||
.existsSafe(filepath)
|
||||
.pipe(Effect.flatMap((exists) => (exists ? fs.readFileString(filepath) : Effect.succeed("")))),
|
||||
),
|
||||
)
|
||||
const newContent = getNewContent(content, diff)
|
||||
|
||||
if (newContent) {
|
||||
|
||||
@@ -7,11 +7,11 @@ import { Agent } from "../../agent/agent"
|
||||
import { Provider } from "../../provider/provider"
|
||||
import path from "path"
|
||||
import fs from "fs/promises"
|
||||
import { Filesystem } from "../../util/filesystem"
|
||||
import matter from "gray-matter"
|
||||
import { Instance } from "../../project/instance"
|
||||
import { EOL } from "os"
|
||||
import type { Argv } from "yargs"
|
||||
import { AppFileSystem } from "@opencode-ai/shared/filesystem"
|
||||
|
||||
type AgentMode = "all" | "primary" | "subagent"
|
||||
|
||||
@@ -194,7 +194,7 @@ const AgentCreateCommand = cmd({
|
||||
|
||||
await fs.mkdir(targetPath, { recursive: true })
|
||||
|
||||
if (await Filesystem.exists(filePath)) {
|
||||
if (await AppRuntime.runPromise(AppFileSystem.Service.use((fs) => fs.existsSafe(filePath)))) {
|
||||
if (isFullyNonInteractive) {
|
||||
console.error(`Error: Agent file already exists: ${filePath}`)
|
||||
process.exit(1)
|
||||
@@ -203,7 +203,7 @@ const AgentCreateCommand = cmd({
|
||||
throw new UI.CancelledError()
|
||||
}
|
||||
|
||||
await Filesystem.write(filePath, content)
|
||||
await AppRuntime.runPromise(AppFileSystem.Service.use((fs) => fs.writeWithDirs(filePath, content)))
|
||||
|
||||
if (isFullyNonInteractive) {
|
||||
console.log(filePath)
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import path from "path"
|
||||
import { exec } from "child_process"
|
||||
import { Filesystem } from "../../util/filesystem"
|
||||
import * as prompts from "@clack/prompts"
|
||||
import { map, pipe, sortBy, values } from "remeda"
|
||||
import { Octokit } from "@octokit/rest"
|
||||
@@ -34,6 +33,7 @@ import { Git } from "@/git"
|
||||
import { setTimeout as sleep } from "node:timers/promises"
|
||||
import { Process } from "@/util/process"
|
||||
import { Effect } from "effect"
|
||||
import { AppFileSystem } from "@opencode-ai/shared/filesystem"
|
||||
|
||||
type GitHubAuthor = {
|
||||
login: string
|
||||
@@ -381,9 +381,11 @@ export const GithubInstallCommand = cmd({
|
||||
? ""
|
||||
: `\n env:${providers[provider].env.map((e) => `\n ${e}: \${{ secrets.${e} }}`).join("")}`
|
||||
|
||||
await Filesystem.write(
|
||||
path.join(app.root, WORKFLOW_FILE),
|
||||
`name: opencode
|
||||
await AppRuntime.runPromise(
|
||||
AppFileSystem.Service.use((fs) =>
|
||||
fs.writeWithDirs(
|
||||
path.join(app.root, WORKFLOW_FILE),
|
||||
`name: opencode
|
||||
|
||||
on:
|
||||
issue_comment:
|
||||
@@ -414,6 +416,8 @@ jobs:
|
||||
uses: anomalyco/opencode/github@latest${envStr}
|
||||
with:
|
||||
model: ${provider}/${model}`,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
prompts.log.success(`Added workflow file: "${WORKFLOW_FILE}"`)
|
||||
|
||||
@@ -9,8 +9,8 @@ import { SessionTable, MessageTable, PartTable } from "../../session/session.sql
|
||||
import { Instance } from "../../project/instance"
|
||||
import { ShareNext } from "../../share/share-next"
|
||||
import { EOL } from "os"
|
||||
import { Filesystem } from "../../util/filesystem"
|
||||
import { AppRuntime } from "@/effect/app-runtime"
|
||||
import { AppFileSystem } from "@opencode-ai/shared/filesystem"
|
||||
|
||||
/** Discriminated union returned by the ShareNext API (GET /api/shares/:id/data) */
|
||||
export type ShareData =
|
||||
@@ -140,7 +140,9 @@ export const ImportCommand = cmd({
|
||||
|
||||
exportData = transformed
|
||||
} else {
|
||||
exportData = await Filesystem.readJson<NonNullable<typeof exportData>>(args.file).catch(() => undefined)
|
||||
exportData = (await AppRuntime.runPromise(AppFileSystem.Service.use((fs) => fs.readJson(args.file))).catch(
|
||||
() => undefined,
|
||||
)) as NonNullable<typeof exportData> | undefined
|
||||
if (!exportData) {
|
||||
process.stdout.write(`File not found: ${args.file}`)
|
||||
process.stdout.write(EOL)
|
||||
|
||||
@@ -13,10 +13,10 @@ import { Installation } from "../../installation"
|
||||
import path from "path"
|
||||
import { Global } from "../../global"
|
||||
import { modify, applyEdits } from "jsonc-parser"
|
||||
import { Filesystem } from "../../util/filesystem"
|
||||
import { Bus } from "../../bus"
|
||||
import { AppRuntime } from "../../effect/app-runtime"
|
||||
import { Effect } from "effect"
|
||||
import { AppFileSystem } from "@opencode-ai/shared/filesystem"
|
||||
|
||||
function getAuthStatusIcon(status: MCP.AuthStatus): string {
|
||||
switch (status) {
|
||||
@@ -416,7 +416,7 @@ async function resolveConfigPath(baseDir: string, global = false) {
|
||||
}
|
||||
|
||||
for (const candidate of candidates) {
|
||||
if (await Filesystem.exists(candidate)) {
|
||||
if (await AppRuntime.runPromise(AppFileSystem.Service.use((fs) => fs.existsSafe(candidate)))) {
|
||||
return candidate
|
||||
}
|
||||
}
|
||||
@@ -427,8 +427,8 @@ async function resolveConfigPath(baseDir: string, global = false) {
|
||||
|
||||
async function addMcpToConfig(name: string, mcpConfig: Config.Mcp, configPath: string) {
|
||||
let text = "{}"
|
||||
if (await Filesystem.exists(configPath)) {
|
||||
text = await Filesystem.readText(configPath)
|
||||
if (await AppRuntime.runPromise(AppFileSystem.Service.use((fs) => fs.existsSafe(configPath)))) {
|
||||
text = await AppRuntime.runPromise(AppFileSystem.Service.use((fs) => fs.readFileString(configPath)))
|
||||
}
|
||||
|
||||
// Use jsonc-parser to modify while preserving comments
|
||||
@@ -437,7 +437,7 @@ async function addMcpToConfig(name: string, mcpConfig: Config.Mcp, configPath: s
|
||||
})
|
||||
const result = applyEdits(text, edits)
|
||||
|
||||
await Filesystem.write(configPath, result)
|
||||
await AppRuntime.runPromise(AppFileSystem.Service.use((fs) => fs.writeWithDirs(configPath, result)))
|
||||
|
||||
return configPath
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import type { Argv } from "yargs"
|
||||
import path from "path"
|
||||
import { pathToFileURL } from "url"
|
||||
import { AppFileSystem } from "@opencode-ai/shared/filesystem"
|
||||
import { UI } from "../ui"
|
||||
import { cmd } from "./cmd"
|
||||
import { Flag } from "../../flag/flag"
|
||||
import { bootstrap } from "../bootstrap"
|
||||
import { EOL } from "os"
|
||||
import { Filesystem } from "../../util/filesystem"
|
||||
import { createOpencodeClient, type OpencodeClient, type ToolPart } from "@opencode-ai/sdk/v2"
|
||||
import { Server } from "../../server/server"
|
||||
import { Provider } from "../../provider/provider"
|
||||
@@ -332,12 +332,14 @@ export const RunCommand = cmd({
|
||||
|
||||
for (const filePath of list) {
|
||||
const resolvedPath = path.resolve(process.cwd(), filePath)
|
||||
if (!(await Filesystem.exists(resolvedPath))) {
|
||||
if (!(await AppRuntime.runPromise(AppFileSystem.Service.use((fs) => fs.existsSafe(resolvedPath))))) {
|
||||
UI.error(`File not found: ${filePath}`)
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
const mime = (await Filesystem.isDir(resolvedPath)) ? "application/x-directory" : "text/plain"
|
||||
const mime = (await AppRuntime.runPromise(AppFileSystem.Service.use((fs) => fs.isDir(resolvedPath))))
|
||||
? "application/x-directory"
|
||||
: "text/plain"
|
||||
|
||||
files.push({
|
||||
type: "file",
|
||||
|
||||
@@ -7,8 +7,8 @@ import { Global } from "../../global"
|
||||
import fs from "fs/promises"
|
||||
import path from "path"
|
||||
import os from "os"
|
||||
import { Filesystem } from "../../util/filesystem"
|
||||
import { Process } from "../../util/process"
|
||||
import { AppFileSystem } from "@opencode-ai/shared/filesystem"
|
||||
|
||||
interface UninstallArgs {
|
||||
keepConfig: boolean
|
||||
@@ -266,7 +266,9 @@ async function getShellConfigFile(): Promise<string | null> {
|
||||
.catch(() => false)
|
||||
if (!exists) continue
|
||||
|
||||
const content = await Filesystem.readText(file).catch(() => "")
|
||||
const content = await AppRuntime.runPromise(AppFileSystem.Service.use((fs) => fs.readFileString(file))).catch(
|
||||
() => "",
|
||||
)
|
||||
if (content.includes("# opencode") || content.includes(".opencode/bin")) {
|
||||
return file
|
||||
}
|
||||
@@ -276,7 +278,7 @@ async function getShellConfigFile(): Promise<string | null> {
|
||||
}
|
||||
|
||||
async function cleanShellConfig(file: string) {
|
||||
const content = await Filesystem.readText(file)
|
||||
const content = await AppRuntime.runPromise(AppFileSystem.Service.use((fs) => fs.readFileString(file)))
|
||||
const lines = content.split("\n")
|
||||
|
||||
const filtered: string[] = []
|
||||
@@ -312,7 +314,7 @@ async function cleanShellConfig(file: string) {
|
||||
}
|
||||
|
||||
const output = filtered.join("\n") + "\n"
|
||||
await Filesystem.write(file, output)
|
||||
await AppRuntime.runPromise(AppFileSystem.Service.use((fs) => fs.writeWithDirs(file, output)))
|
||||
}
|
||||
|
||||
async function getDirectorySize(dir: string): Promise<number> {
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { NamedError } from "@opencode-ai/shared/util/error"
|
||||
import { AppFileSystem } from "@opencode-ai/shared/filesystem"
|
||||
import matter from "gray-matter"
|
||||
import { z } from "zod"
|
||||
import { Filesystem } from "../util/filesystem"
|
||||
import { AppRuntime } from "@/effect/app-runtime"
|
||||
|
||||
export namespace ConfigMarkdown {
|
||||
export const FILE_REGEX = /(?<![\w`])@(\.?[^\s`,.]*(?:\.[^\s`,.]+)*)/g
|
||||
@@ -69,7 +70,7 @@ export namespace ConfigMarkdown {
|
||||
}
|
||||
|
||||
export async function parse(filePath: string) {
|
||||
const template = await Filesystem.readText(filePath)
|
||||
const template = await AppRuntime.runPromise(AppFileSystem.Service.use((fs) => fs.readFileString(filePath)))
|
||||
|
||||
try {
|
||||
const md = matter(template)
|
||||
|
||||
@@ -9,9 +9,9 @@ import { SyncEvent } from "@/sync"
|
||||
import { EventTable } from "@/sync/event.sql"
|
||||
import { Flag } from "@/flag/flag"
|
||||
import { Log } from "@/util/log"
|
||||
import { Filesystem } from "@/util/filesystem"
|
||||
import { ProjectID } from "@/project/schema"
|
||||
import { Slug } from "@opencode-ai/shared/util/slug"
|
||||
import { AppFileSystem } from "@opencode-ai/shared/filesystem"
|
||||
import { WorkspaceTable } from "./workspace.sql"
|
||||
import { getAdaptor } from "./adaptors"
|
||||
import { WorkspaceInfo } from "./types"
|
||||
@@ -418,7 +418,7 @@ export namespace Workspace {
|
||||
if (!Flag.OPENCODE_EXPERIMENTAL_WORKSPACES) return
|
||||
|
||||
if (space.type === "worktree") {
|
||||
void Filesystem.exists(space.directory!).then((exists) => {
|
||||
void AppRuntime.runPromise(AppFileSystem.Service.use((fs) => fs.existsSafe(space.directory!))).then((exists) => {
|
||||
setStatus(space.id, exists ? "connected" : "error", exists ? undefined : "directory does not exist")
|
||||
})
|
||||
return
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import fs from "fs/promises"
|
||||
import path from "path"
|
||||
import { fileURLToPath } from "url"
|
||||
import { AppFileSystem } from "@opencode-ai/shared/filesystem"
|
||||
import z from "zod"
|
||||
import { Cause, Context, Effect, Layer, Queue, Stream } from "effect"
|
||||
import { ripgrep } from "ripgrep"
|
||||
import { makeRuntime } from "@/effect/run-service"
|
||||
import { Filesystem } from "@/util/filesystem"
|
||||
import { Log } from "@/util/log"
|
||||
|
||||
export namespace Ripgrep {
|
||||
@@ -275,10 +275,11 @@ export namespace Ripgrep {
|
||||
return Effect.succeed(OPENCODE_RIPGREP_WORKER_PATH)
|
||||
}
|
||||
const js = new URL("./ripgrep.worker.js", import.meta.url)
|
||||
return Effect.tryPromise({
|
||||
try: () => Filesystem.exists(fileURLToPath(js)),
|
||||
catch: toError,
|
||||
}).pipe(Effect.map((exists) => (exists ? js : new URL("./ripgrep.worker.ts", import.meta.url))))
|
||||
return Effect.gen(function* () {
|
||||
const fs = yield* AppFileSystem.Service
|
||||
const exists = yield* fs.exists(fileURLToPath(js)).pipe(Effect.orElseSucceed(() => false))
|
||||
return exists ? js : new URL("./ripgrep.worker.ts", import.meta.url)
|
||||
})
|
||||
}
|
||||
|
||||
function worker() {
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import fs from "fs/promises"
|
||||
import { AppFileSystem } from "@opencode-ai/shared/filesystem"
|
||||
import { xdgData, xdgCache, xdgConfig, xdgState } from "xdg-basedir"
|
||||
import path from "path"
|
||||
import os from "os"
|
||||
import { Filesystem } from "../util/filesystem"
|
||||
import { Effect } from "effect"
|
||||
|
||||
const app = "opencode"
|
||||
|
||||
@@ -36,7 +37,11 @@ await Promise.all([
|
||||
|
||||
const CACHE_VERSION = "21"
|
||||
|
||||
const version = await Filesystem.readText(path.join(Global.Path.cache, "version")).catch(() => "0")
|
||||
const version = await Effect.runPromise(
|
||||
AppFileSystem.Service.use((fs) => fs.readFileString(path.join(Global.Path.cache, "version"))).pipe(
|
||||
Effect.provide(AppFileSystem.defaultLayer),
|
||||
),
|
||||
).catch(() => "0")
|
||||
|
||||
if (version !== CACHE_VERSION) {
|
||||
try {
|
||||
@@ -50,5 +55,9 @@ if (version !== CACHE_VERSION) {
|
||||
),
|
||||
)
|
||||
} catch (e) {}
|
||||
await Filesystem.write(path.join(Global.Path.cache, "version"), CACHE_VERSION)
|
||||
await Effect.runPromise(
|
||||
AppFileSystem.Service.use((fs) => fs.writeWithDirs(path.join(Global.Path.cache, "version"), CACHE_VERSION)).pipe(
|
||||
Effect.provide(AppFileSystem.defaultLayer),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -11,10 +11,10 @@ import { UninstallCommand } from "./cli/cmd/uninstall"
|
||||
import { ModelsCommand } from "./cli/cmd/models"
|
||||
import { UI } from "./cli/ui"
|
||||
import { Installation } from "./installation"
|
||||
import { AppFileSystem } from "@opencode-ai/shared/filesystem"
|
||||
import { NamedError } from "@opencode-ai/shared/util/error"
|
||||
import { FormatError } from "./cli/error"
|
||||
import { ServeCommand } from "./cli/cmd/serve"
|
||||
import { Filesystem } from "./util/filesystem"
|
||||
import { DebugCommand } from "./cli/cmd/debug"
|
||||
import { StatsCommand } from "./cli/cmd/stats"
|
||||
import { McpCommand } from "./cli/cmd/mcp"
|
||||
@@ -37,6 +37,7 @@ import { errorMessage } from "./util/error"
|
||||
import { PluginCommand } from "./cli/cmd/plug"
|
||||
import { Heap } from "./cli/heap"
|
||||
import { drizzle } from "drizzle-orm/bun-sqlite"
|
||||
import { AppRuntime } from "@/effect/app-runtime"
|
||||
|
||||
process.on("unhandledRejection", (e) => {
|
||||
Log.Default.error("rejection", {
|
||||
@@ -110,7 +111,7 @@ const cli = yargs(args)
|
||||
})
|
||||
|
||||
const marker = path.join(Global.Path.data, "opencode.db")
|
||||
if (!(await Filesystem.exists(marker))) {
|
||||
if (!(await AppRuntime.runPromise(AppFileSystem.Service.use((fs) => fs.existsSafe(marker))))) {
|
||||
const tty = process.stderr.isTTY
|
||||
process.stderr.write("Performing one time database migration, may take a few minutes..." + EOL)
|
||||
const width = 36
|
||||
|
||||
Reference in New Issue
Block a user