Add packages/opencode-config and use it
This commit is contained in:
3
packages/opencode-config/opencode.jsonc
Normal file
3
packages/opencode-config/opencode.jsonc
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://opencode.ai/config.json"
|
||||||
|
}
|
||||||
18
packages/opencode-config/plugin/hello.js
Normal file
18
packages/opencode-config/plugin/hello.js
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import { tool } from "@opencode-ai/plugin/tool"
|
||||||
|
|
||||||
|
export async function HelloPlugin() {
|
||||||
|
return {
|
||||||
|
tool: {
|
||||||
|
hello: tool({
|
||||||
|
description: "Return a friendly greeting",
|
||||||
|
args: {
|
||||||
|
name: tool.schema.string().optional().describe("Name to greet"),
|
||||||
|
},
|
||||||
|
async execute(args) {
|
||||||
|
const target = args.name?.trim() || "CodeNomad"
|
||||||
|
return `Hello, ${target}!`
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,10 +16,11 @@
|
|||||||
"codenomad": "dist/bin.js"
|
"codenomad": "dist/bin.js"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "npm run build:ui && npm run prepare-ui && tsc -p tsconfig.json",
|
"build": "npm run build:ui && npm run prepare-ui && tsc -p tsconfig.json && npm run prepare-config",
|
||||||
"build:ui": "npm run build --prefix ../ui",
|
"build:ui": "npm run build --prefix ../ui",
|
||||||
"prepare-ui": "node ./scripts/copy-ui-dist.mjs",
|
"prepare-ui": "node ./scripts/copy-ui-dist.mjs",
|
||||||
"dev": "cross-env CLI_UI_DEV_SERVER=http://localhost:3000 tsx src/index.ts",
|
"prepare-config": "node ./scripts/copy-opencode-config.mjs",
|
||||||
|
"dev": "cross-env CODENOMAD_DEV=1 CLI_UI_DEV_SERVER=http://localhost:3000 tsx src/index.ts",
|
||||||
"typecheck": "tsc --noEmit -p tsconfig.json"
|
"typecheck": "tsc --noEmit -p tsconfig.json"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
21
packages/server/scripts/copy-opencode-config.mjs
Normal file
21
packages/server/scripts/copy-opencode-config.mjs
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
import { cpSync, existsSync, mkdirSync, rmSync } from "fs"
|
||||||
|
import path from "path"
|
||||||
|
import { fileURLToPath } from "url"
|
||||||
|
|
||||||
|
const __filename = fileURLToPath(import.meta.url)
|
||||||
|
const __dirname = path.dirname(__filename)
|
||||||
|
const cliRoot = path.resolve(__dirname, "..")
|
||||||
|
const sourceDir = path.resolve(cliRoot, "../opencode-config")
|
||||||
|
const targetDir = path.resolve(cliRoot, "dist/opencode-config")
|
||||||
|
|
||||||
|
if (!existsSync(sourceDir)) {
|
||||||
|
console.error(`[copy-opencode-config] Missing source directory at ${sourceDir}`)
|
||||||
|
process.exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
rmSync(targetDir, { recursive: true, force: true })
|
||||||
|
mkdirSync(path.dirname(targetDir), { recursive: true })
|
||||||
|
cpSync(sourceDir, targetDir, { recursive: true })
|
||||||
|
|
||||||
|
console.log(`[copy-opencode-config] Copied ${sourceDir} -> ${targetDir}`)
|
||||||
36
packages/server/src/opencode-config.ts
Normal file
36
packages/server/src/opencode-config.ts
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
import { cpSync, existsSync, mkdirSync, rmSync } from "fs"
|
||||||
|
import os from "os"
|
||||||
|
import path from "path"
|
||||||
|
import { fileURLToPath } from "url"
|
||||||
|
import { createLogger } from "./logger"
|
||||||
|
|
||||||
|
const log = createLogger({ component: "opencode-config" })
|
||||||
|
const __filename = fileURLToPath(import.meta.url)
|
||||||
|
const __dirname = path.dirname(__filename)
|
||||||
|
const devTemplateDir = path.resolve(__dirname, "../../opencode-config")
|
||||||
|
const prodTemplateDir = path.resolve(__dirname, "opencode-config")
|
||||||
|
|
||||||
|
const isDevBuild = Boolean(process.env.CODENOMAD_DEV ?? process.env.CLI_UI_DEV_SERVER) || existsSync(devTemplateDir)
|
||||||
|
const templateDir = isDevBuild ? devTemplateDir : prodTemplateDir
|
||||||
|
const userConfigDir = path.join(os.homedir(), ".config", "codenomad", "opencode-config")
|
||||||
|
|
||||||
|
export function getOpencodeConfigDir(): string {
|
||||||
|
if (!existsSync(templateDir)) {
|
||||||
|
throw new Error(`CodeNomad Opencode config template missing at ${templateDir}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isDevBuild) {
|
||||||
|
log.debug({ templateDir }, "Using Opencode config template directly (dev mode)")
|
||||||
|
return templateDir
|
||||||
|
}
|
||||||
|
|
||||||
|
refreshUserConfig()
|
||||||
|
return userConfigDir
|
||||||
|
}
|
||||||
|
|
||||||
|
function refreshUserConfig() {
|
||||||
|
log.debug({ templateDir, userConfigDir }, "Syncing Opencode config template")
|
||||||
|
rmSync(userConfigDir, { recursive: true, force: true })
|
||||||
|
mkdirSync(path.dirname(userConfigDir), { recursive: true })
|
||||||
|
cpSync(templateDir, userConfigDir, { recursive: true })
|
||||||
|
}
|
||||||
@@ -9,6 +9,7 @@ import { clearWorkspaceSearchCache } from "../filesystem/search-cache"
|
|||||||
import { WorkspaceDescriptor, WorkspaceFileResponse, FileSystemEntry } from "../api-types"
|
import { WorkspaceDescriptor, WorkspaceFileResponse, FileSystemEntry } from "../api-types"
|
||||||
import { WorkspaceRuntime } from "./runtime"
|
import { WorkspaceRuntime } from "./runtime"
|
||||||
import { Logger } from "../logger"
|
import { Logger } from "../logger"
|
||||||
|
import { getOpencodeConfigDir } from "../opencode-config"
|
||||||
|
|
||||||
interface WorkspaceManagerOptions {
|
interface WorkspaceManagerOptions {
|
||||||
rootDir: string
|
rootDir: string
|
||||||
@@ -23,9 +24,11 @@ interface WorkspaceRecord extends WorkspaceDescriptor {}
|
|||||||
export class WorkspaceManager {
|
export class WorkspaceManager {
|
||||||
private readonly workspaces = new Map<string, WorkspaceRecord>()
|
private readonly workspaces = new Map<string, WorkspaceRecord>()
|
||||||
private readonly runtime: WorkspaceRuntime
|
private readonly runtime: WorkspaceRuntime
|
||||||
|
private readonly opencodeConfigDir: string
|
||||||
|
|
||||||
constructor(private readonly options: WorkspaceManagerOptions) {
|
constructor(private readonly options: WorkspaceManagerOptions) {
|
||||||
this.runtime = new WorkspaceRuntime(this.options.eventBus, this.options.logger)
|
this.runtime = new WorkspaceRuntime(this.options.eventBus, this.options.logger)
|
||||||
|
this.opencodeConfigDir = getOpencodeConfigDir()
|
||||||
}
|
}
|
||||||
|
|
||||||
list(): WorkspaceDescriptor[] {
|
list(): WorkspaceDescriptor[] {
|
||||||
@@ -97,7 +100,12 @@ export class WorkspaceManager {
|
|||||||
|
|
||||||
this.options.eventBus.publish({ type: "workspace.created", workspace: descriptor })
|
this.options.eventBus.publish({ type: "workspace.created", workspace: descriptor })
|
||||||
|
|
||||||
const environment = this.options.configStore.get().preferences.environmentVariables ?? {}
|
const preferences = this.options.configStore.get().preferences ?? {}
|
||||||
|
const userEnvironment = preferences.environmentVariables ?? {}
|
||||||
|
const environment = {
|
||||||
|
...userEnvironment,
|
||||||
|
OPENCODE_CONFIG_DIR: this.opencodeConfigDir,
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const { pid, port } = await this.runtime.launch({
|
const { pid, port } = await this.runtime.launch({
|
||||||
|
|||||||
Reference in New Issue
Block a user