diff --git a/Dockerfile b/Dockerfile index 8a5fcba..13f366c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -22,6 +22,7 @@ WORKDIR /app ENV NODE_ENV=production ENV HOST=0.0.0.0 ENV PORT=8787 +ENV PATH=/app/node_modules/.bin:/app/.opencode/node_modules/.bin:$PATH COPY --from=deps /app/node_modules ./node_modules COPY --from=deps /app/.opencode/node_modules ./.opencode/node_modules diff --git a/src/runtime/opencode.ts b/src/runtime/opencode.ts index 678747e..694fb59 100644 --- a/src/runtime/opencode.ts +++ b/src/runtime/opencode.ts @@ -99,6 +99,8 @@ export class OpencodeRuntimeAdapter { } private async bootstrapClient(): Promise { + ensureLocalBinPath(); + if (config.OPENCODE_BASE_URL) { logger.info( { baseUrl: config.OPENCODE_BASE_URL }, @@ -113,7 +115,9 @@ export class OpencodeRuntimeAdapter { // 这样 .opencode/tools 下的自定义工具可以回调本服务。 process.env.TJWATER_AGENT_INTERNAL_BASE_URL = `http://127.0.0.1:${config.PORT}`; process.env.TJWATER_AGENT_INTERNAL_TOKEN = - config.AGENT_INTERNAL_TOKEN ?? process.env.TJWATER_AGENT_INTERNAL_TOKEN ?? ""; + config.AGENT_INTERNAL_TOKEN ?? + process.env.TJWATER_AGENT_INTERNAL_TOKEN ?? + ""; logger.info( { @@ -143,6 +147,23 @@ export class OpencodeRuntimeAdapter { export const opencodeRuntime = new OpencodeRuntimeAdapter(); +function ensureLocalBinPath(): void { + const cwd = process.cwd(); + const delimiter = process.platform === "win32" ? ";" : ":"; + const candidates = [ + `${cwd}/node_modules/.bin`, + `${cwd}/.opencode/node_modules/.bin`, + ]; + const currentPath = process.env.PATH ?? ""; + const segments = currentPath.split(delimiter).filter(Boolean); + const next = [ + ...candidates.filter((candidate) => !segments.includes(candidate)), + ...segments, + ]; + + process.env.PATH = next.join(delimiter); +} + function requireData(data: T | undefined, operation: string): T { if (data === undefined) { throw new Error(`${operation} returned no data`);