mirror of
https://github.com/anomalyco/opencode.git
synced 2026-05-22 11:25:15 +00:00
chore: delete unused files across opencode
Remove dead scripts, spec files, TUI components, and a duplicate test fixture that knip flagged as unused. Verified each by grepping for any dynamic / string / URL references before deleting. Files removed: - script/check-migrations.ts (no references) - script/time.ts (no references) - script/trace-imports.ts (no references; hardcoded dev path) - specs/v2/api.ts (@ts-nocheck design spec, no references) - src/cli/cmd/tui/component/dialog-tag.tsx (not imported) - src/cli/cmd/tui/routes/session/dialog-subagent.tsx (not imported) - src/cli/cmd/tui/routes/session/footer.tsx (session uses subagent-footer) - test/fixture/flock-worker.ts (duplicate; core has its own copy)
This commit is contained in:
parent
2935d1819e
commit
292a449632
8 changed files with 0 additions and 478 deletions
|
|
@ -1,16 +0,0 @@
|
|||
#!/usr/bin/env bun
|
||||
|
||||
import { $ } from "bun"
|
||||
|
||||
// drizzle-kit check compares schema to migrations, exits non-zero if drift
|
||||
const result = await $`bun drizzle-kit check`.quiet().nothrow()
|
||||
|
||||
if (result.exitCode !== 0) {
|
||||
console.error("Schema has changes not captured in migrations!")
|
||||
console.error("Run: bun drizzle-kit generate")
|
||||
console.error("")
|
||||
console.error(result.stderr.toString())
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
console.log("Migrations are up to date")
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
#!/usr/bin/env bun
|
||||
|
||||
import path from "path"
|
||||
const toDynamicallyImport = path.join(process.cwd(), process.argv[2])
|
||||
await import(toDynamicallyImport)
|
||||
console.log(performance.now())
|
||||
|
|
@ -1,153 +0,0 @@
|
|||
#!/usr/bin/env bun
|
||||
import * as path from "path"
|
||||
import * as ts from "typescript"
|
||||
|
||||
const BASE_DIR = "/home/thdxr/dev/projects/anomalyco/opencode/packages/opencode"
|
||||
|
||||
// Get entry file from command line arg or use default
|
||||
const ENTRY_FILE = process.argv[2] || "src/cli/cmd/tui/plugin/index.ts"
|
||||
|
||||
const visited = new Set<string>()
|
||||
|
||||
function resolveImport(importPath: string, fromFile: string): string | null {
|
||||
if (importPath.startsWith("@/")) {
|
||||
return path.join(BASE_DIR, "src", importPath.slice(2))
|
||||
}
|
||||
|
||||
if (importPath.startsWith("./") || importPath.startsWith("../")) {
|
||||
const dir = path.dirname(fromFile)
|
||||
return path.resolve(dir, importPath)
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
function isInternalImport(importPath: string): boolean {
|
||||
return importPath.startsWith("@/") || importPath.startsWith("./") || importPath.startsWith("../")
|
||||
}
|
||||
|
||||
async function tryExtensions(filePath: string): Promise<string | null> {
|
||||
const extensions = [".ts", ".tsx", ".js", ".jsx"]
|
||||
|
||||
try {
|
||||
const file = Bun.file(filePath)
|
||||
const stat = await file.stat()
|
||||
|
||||
if (stat?.isDirectory()) {
|
||||
for (const ext of extensions) {
|
||||
const indexPath = path.join(filePath, "index" + ext)
|
||||
const indexFile = Bun.file(indexPath)
|
||||
if (await indexFile.exists()) return indexPath
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
// It's a file
|
||||
return filePath
|
||||
} catch {
|
||||
// Path doesn't exist, try adding extensions
|
||||
for (const ext of extensions) {
|
||||
const withExt = filePath + ext
|
||||
const extFile = Bun.file(withExt)
|
||||
if (await extFile.exists()) return withExt
|
||||
}
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
function extractImports(sourceFile: ts.SourceFile): string[] {
|
||||
const imports: string[] = []
|
||||
|
||||
function visit(node: ts.Node) {
|
||||
// import x from "path" or import { x } from "path"
|
||||
if (ts.isImportDeclaration(node)) {
|
||||
// Skip type-only imports
|
||||
if (node.importClause?.isTypeOnly) return
|
||||
|
||||
const moduleSpec = node.moduleSpecifier
|
||||
if (ts.isStringLiteral(moduleSpec)) {
|
||||
imports.push(moduleSpec.text)
|
||||
}
|
||||
}
|
||||
|
||||
// export { x } from "path"
|
||||
if (ts.isExportDeclaration(node) && node.moduleSpecifier) {
|
||||
if (ts.isStringLiteral(node.moduleSpecifier)) {
|
||||
imports.push(node.moduleSpecifier.text)
|
||||
}
|
||||
}
|
||||
|
||||
// Dynamic import: import("path")
|
||||
if (ts.isCallExpression(node) && node.expression.kind === ts.SyntaxKind.ImportKeyword) {
|
||||
const arg = node.arguments[0]
|
||||
if (arg && ts.isStringLiteral(arg)) {
|
||||
imports.push(arg.text)
|
||||
}
|
||||
}
|
||||
|
||||
ts.forEachChild(node, visit)
|
||||
}
|
||||
|
||||
visit(sourceFile)
|
||||
return imports
|
||||
}
|
||||
|
||||
async function traceFile(filePath: string, depth = 0): Promise<void> {
|
||||
const normalizedPath = path.relative(BASE_DIR, filePath)
|
||||
|
||||
if (visited.has(filePath)) {
|
||||
return
|
||||
}
|
||||
|
||||
// Only trace TypeScript/JavaScript files
|
||||
if (!filePath.match(/\.(ts|tsx|js|jsx)$/)) {
|
||||
return
|
||||
}
|
||||
|
||||
visited.add(filePath)
|
||||
console.log("\t".repeat(depth) + normalizedPath)
|
||||
|
||||
let content: string
|
||||
try {
|
||||
content = await Bun.file(filePath).text()
|
||||
} catch {
|
||||
return
|
||||
}
|
||||
|
||||
const sourceFile = ts.createSourceFile(filePath, content, ts.ScriptTarget.Latest, true)
|
||||
|
||||
const imports = extractImports(sourceFile)
|
||||
const internalImports = imports.filter(isInternalImport)
|
||||
const externalImports = imports.filter((imp) => !isInternalImport(imp))
|
||||
|
||||
// Print external imports
|
||||
for (const imp of externalImports) {
|
||||
console.log("\t".repeat(depth + 1) + `[ext] ${imp}`)
|
||||
}
|
||||
|
||||
for (const imp of internalImports) {
|
||||
const resolved = resolveImport(imp, filePath)
|
||||
if (!resolved) continue
|
||||
|
||||
const actualPath = await tryExtensions(resolved)
|
||||
if (!actualPath) continue
|
||||
|
||||
await traceFile(actualPath, depth + 1)
|
||||
}
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const entryPath = path.join(BASE_DIR, ENTRY_FILE)
|
||||
|
||||
// Check if file exists
|
||||
const file = Bun.file(entryPath)
|
||||
if (!(await file.exists())) {
|
||||
console.error(`File not found: ${ENTRY_FILE}`)
|
||||
console.error(`Resolved to: ${entryPath}`)
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
await traceFile(entryPath)
|
||||
}
|
||||
|
||||
main().catch(console.error)
|
||||
|
|
@ -1,67 +0,0 @@
|
|||
// @ts-nocheck
|
||||
|
||||
import { OpenCode } from "@opencode-ai/core"
|
||||
import { ReadTool } from "@opencode-ai/core/tools"
|
||||
|
||||
const opencode = OpenCode.make({})
|
||||
|
||||
opencode.tool.add(ReadTool)
|
||||
|
||||
opencode.tool.add({
|
||||
name: "bash",
|
||||
schema: {
|
||||
type: "object",
|
||||
properties: {
|
||||
command: {
|
||||
type: "string",
|
||||
description: "The command to run.",
|
||||
},
|
||||
},
|
||||
required: ["command"],
|
||||
},
|
||||
execute(input, ctx) {},
|
||||
})
|
||||
|
||||
opencode.auth.add({
|
||||
provider: "openai",
|
||||
type: "api",
|
||||
value: process.env.OPENAI_API_KEY,
|
||||
})
|
||||
|
||||
opencode.agent.add({
|
||||
name: "build",
|
||||
permissions: [],
|
||||
model: {
|
||||
id: "gpt-5-5",
|
||||
provider: "openai",
|
||||
variant: "xhigh",
|
||||
},
|
||||
})
|
||||
|
||||
const sessionID = await opencode.session.create({
|
||||
agent: "build",
|
||||
})
|
||||
|
||||
opencode.subscribe((event) => {
|
||||
console.log(event)
|
||||
})
|
||||
|
||||
await opencode.session.prompt({
|
||||
sessionID,
|
||||
text: "hey what is up",
|
||||
})
|
||||
|
||||
await opencode.session.prompt({
|
||||
sessionID,
|
||||
text: "what is up with this",
|
||||
files: [
|
||||
{
|
||||
mime: "image/png",
|
||||
uri: "data:image/png;base64,xxxx",
|
||||
},
|
||||
],
|
||||
})
|
||||
|
||||
await opencode.session.wait()
|
||||
|
||||
console.log(await opencode.session.messages(sessionID))
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
import { createMemo, createResource } from "solid-js"
|
||||
import { DialogSelect } from "@tui/ui/dialog-select"
|
||||
import { useDialog } from "@tui/ui/dialog"
|
||||
import { useProject } from "@tui/context/project"
|
||||
import { useSDK } from "@tui/context/sdk"
|
||||
import { createStore } from "solid-js/store"
|
||||
|
||||
export function DialogTag(props: { onSelect?: (value: string) => void }) {
|
||||
const sdk = useSDK()
|
||||
const dialog = useDialog()
|
||||
const project = useProject()
|
||||
|
||||
const [store] = createStore({
|
||||
filter: "",
|
||||
})
|
||||
|
||||
const [files] = createResource(
|
||||
() => [store.filter],
|
||||
async () => {
|
||||
const result = await sdk.client.find.files({
|
||||
query: store.filter,
|
||||
workspace: project.workspace.current(),
|
||||
})
|
||||
if (result.error) return []
|
||||
const sliced = (result.data ?? []).slice(0, 5)
|
||||
return sliced
|
||||
},
|
||||
)
|
||||
|
||||
const options = createMemo(() =>
|
||||
(files() ?? []).map((file) => ({
|
||||
value: file,
|
||||
title: file,
|
||||
})),
|
||||
)
|
||||
|
||||
return (
|
||||
<DialogSelect
|
||||
title="Autocomplete"
|
||||
options={options()}
|
||||
onSelect={(option) => {
|
||||
props.onSelect?.(option.value)
|
||||
dialog.clear()
|
||||
}}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
import { DialogSelect } from "@tui/ui/dialog-select"
|
||||
import { useRoute } from "@tui/context/route"
|
||||
|
||||
export function DialogSubagent(props: { sessionID: string }) {
|
||||
const route = useRoute()
|
||||
|
||||
return (
|
||||
<DialogSelect
|
||||
title="Subagent Actions"
|
||||
options={[
|
||||
{
|
||||
title: "Open",
|
||||
value: "subagent.view",
|
||||
description: "the subagent's session",
|
||||
onSelect: (dialog) => {
|
||||
route.navigate({
|
||||
type: "session",
|
||||
sessionID: props.sessionID,
|
||||
})
|
||||
dialog.clear()
|
||||
},
|
||||
},
|
||||
]}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
|
@ -1,91 +0,0 @@
|
|||
import { createMemo, Match, onCleanup, onMount, Show, Switch } from "solid-js"
|
||||
import { useTheme } from "../../context/theme"
|
||||
import { useSync } from "../../context/sync"
|
||||
import { useDirectory } from "../../context/directory"
|
||||
import { useConnected } from "../../component/use-connected"
|
||||
import { createStore } from "solid-js/store"
|
||||
import { useRoute } from "../../context/route"
|
||||
|
||||
export function Footer() {
|
||||
const { theme } = useTheme()
|
||||
const sync = useSync()
|
||||
const route = useRoute()
|
||||
const mcp = createMemo(() => Object.values(sync.data.mcp).filter((x) => x.status === "connected").length)
|
||||
const mcpError = createMemo(() => Object.values(sync.data.mcp).some((x) => x.status === "failed"))
|
||||
const lsp = createMemo(() => Object.keys(sync.data.lsp))
|
||||
const permissions = createMemo(() => {
|
||||
if (route.data.type !== "session") return []
|
||||
return sync.data.permission[route.data.sessionID] ?? []
|
||||
})
|
||||
const directory = useDirectory()
|
||||
const connected = useConnected()
|
||||
|
||||
const [store, setStore] = createStore({
|
||||
welcome: false,
|
||||
})
|
||||
|
||||
onMount(() => {
|
||||
// Track all timeouts to ensure proper cleanup
|
||||
const timeouts: ReturnType<typeof setTimeout>[] = []
|
||||
|
||||
function tick() {
|
||||
if (connected()) return
|
||||
if (!store.welcome) {
|
||||
setStore("welcome", true)
|
||||
timeouts.push(setTimeout(() => tick(), 5000))
|
||||
return
|
||||
}
|
||||
|
||||
if (store.welcome) {
|
||||
setStore("welcome", false)
|
||||
timeouts.push(setTimeout(() => tick(), 10_000))
|
||||
return
|
||||
}
|
||||
}
|
||||
timeouts.push(setTimeout(() => tick(), 10_000))
|
||||
|
||||
onCleanup(() => {
|
||||
timeouts.forEach(clearTimeout)
|
||||
})
|
||||
})
|
||||
|
||||
return (
|
||||
<box flexDirection="row" justifyContent="space-between" gap={1} flexShrink={0}>
|
||||
<text fg={theme.textMuted}>{directory()}</text>
|
||||
<box gap={2} flexDirection="row" flexShrink={0}>
|
||||
<Switch>
|
||||
<Match when={store.welcome}>
|
||||
<text fg={theme.text}>
|
||||
Get started <span style={{ fg: theme.textMuted }}>/connect</span>
|
||||
</text>
|
||||
</Match>
|
||||
<Match when={connected()}>
|
||||
<Show when={permissions().length > 0}>
|
||||
<text fg={theme.warning}>
|
||||
<span style={{ fg: theme.warning }}>△</span> {permissions().length} Permission
|
||||
{permissions().length > 1 ? "s" : ""}
|
||||
</text>
|
||||
</Show>
|
||||
<text fg={theme.text}>
|
||||
<span style={{ fg: lsp().length > 0 ? theme.success : theme.textMuted }}>•</span> {lsp().length} LSP
|
||||
</text>
|
||||
<Show when={mcp()}>
|
||||
<text fg={theme.text}>
|
||||
<Switch>
|
||||
<Match when={mcpError()}>
|
||||
<span style={{ fg: theme.error }}>⊙ </span>
|
||||
</Match>
|
||||
<Match when={true}>
|
||||
<span style={{ fg: theme.success }}>⊙ </span>
|
||||
</Match>
|
||||
</Switch>
|
||||
{mcp()} MCP
|
||||
</text>
|
||||
</Show>
|
||||
<text fg={theme.textMuted}>/status</text>
|
||||
</Match>
|
||||
</Switch>
|
||||
</box>
|
||||
</box>
|
||||
)
|
||||
}
|
||||
|
|
@ -1,72 +0,0 @@
|
|||
import fs from "fs/promises"
|
||||
import { Flock } from "@opencode-ai/core/util/flock"
|
||||
|
||||
type Msg = {
|
||||
key: string
|
||||
dir: string
|
||||
staleMs?: number
|
||||
timeoutMs?: number
|
||||
baseDelayMs?: number
|
||||
maxDelayMs?: number
|
||||
holdMs?: number
|
||||
ready?: string
|
||||
active?: string
|
||||
done?: string
|
||||
}
|
||||
|
||||
function sleep(ms: number) {
|
||||
return new Promise<void>((resolve) => {
|
||||
setTimeout(resolve, ms)
|
||||
})
|
||||
}
|
||||
|
||||
function input() {
|
||||
const raw = process.argv[2]
|
||||
if (!raw) {
|
||||
throw new Error("Missing flock worker input")
|
||||
}
|
||||
|
||||
return JSON.parse(raw) as Msg
|
||||
}
|
||||
|
||||
async function job(input: Msg) {
|
||||
if (input.ready) {
|
||||
await fs.writeFile(input.ready, String(process.pid))
|
||||
}
|
||||
|
||||
if (input.active) {
|
||||
await fs.writeFile(input.active, String(process.pid), { flag: "wx" })
|
||||
}
|
||||
|
||||
try {
|
||||
if (input.holdMs && input.holdMs > 0) {
|
||||
await sleep(input.holdMs)
|
||||
}
|
||||
|
||||
if (input.done) {
|
||||
await fs.appendFile(input.done, "1\n")
|
||||
}
|
||||
} finally {
|
||||
if (input.active) {
|
||||
await fs.rm(input.active, { force: true })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const msg = input()
|
||||
|
||||
await Flock.withLock(msg.key, () => job(msg), {
|
||||
dir: msg.dir,
|
||||
staleMs: msg.staleMs,
|
||||
timeoutMs: msg.timeoutMs,
|
||||
baseDelayMs: msg.baseDelayMs,
|
||||
maxDelayMs: msg.maxDelayMs,
|
||||
})
|
||||
}
|
||||
|
||||
await main().catch((err) => {
|
||||
const text = err instanceof Error ? (err.stack ?? err.message) : String(err)
|
||||
process.stderr.write(text)
|
||||
process.exit(1)
|
||||
})
|
||||
Loading…
Add table
Add a link
Reference in a new issue