2025-10-28 13:17:06 +05:30
|
|
|
import path from "path";
|
|
|
|
|
import fs from "fs";
|
|
|
|
|
import { McpServerConfig } from "../entities/mcp.js";
|
2025-11-14 09:23:37 +05:30
|
|
|
import { ModelConfig as ModelConfigT } from "../entities/models.js";
|
2025-10-28 13:17:06 +05:30
|
|
|
import { z } from "zod";
|
2025-11-05 13:28:38 +05:30
|
|
|
import { homedir } from "os";
|
2025-10-28 13:17:06 +05:30
|
|
|
|
2025-10-30 16:09:19 +08:00
|
|
|
// Resolve app root relative to compiled file location (dist/...)
|
2025-11-05 13:28:38 +05:30
|
|
|
export const WorkDir = path.join(homedir(), ".rowboat");
|
2025-10-28 13:17:06 +05:30
|
|
|
|
2025-11-14 09:13:28 +05:30
|
|
|
const baseMcpConfig: z.infer<typeof McpServerConfig> = {
|
2025-11-07 11:42:10 +05:30
|
|
|
mcpServers: {
|
|
|
|
|
firecrawl: {
|
|
|
|
|
command: "npx",
|
|
|
|
|
args: ["-y", "supergateway", "--stdio", "npx -y firecrawl-mcp"],
|
|
|
|
|
env: {
|
|
|
|
|
FIRECRAWL_API_KEY: "fc-aaacee4bdd164100a4d83af85bef6fdc",
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
test: {
|
|
|
|
|
url: "http://localhost:3000",
|
|
|
|
|
headers: {
|
|
|
|
|
"Authorization": "Bearer test",
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
}
|
2025-11-14 09:13:28 +05:30
|
|
|
};
|
|
|
|
|
|
2025-11-14 09:23:37 +05:30
|
|
|
const baseModelConfig: z.infer<typeof ModelConfigT> = {
|
2025-11-14 09:13:28 +05:30
|
|
|
providers: {
|
|
|
|
|
openai: {
|
|
|
|
|
flavor: "openai",
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
defaults: {
|
|
|
|
|
provider: "openai",
|
|
|
|
|
model: "gpt-4.1",
|
|
|
|
|
}
|
|
|
|
|
};
|
2025-11-07 11:42:10 +05:30
|
|
|
|
|
|
|
|
function ensureMcpConfig() {
|
|
|
|
|
const configPath = path.join(WorkDir, "config", "mcp.json");
|
|
|
|
|
if (!fs.existsSync(configPath)) {
|
|
|
|
|
fs.writeFileSync(configPath, JSON.stringify(baseMcpConfig, null, 2));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-14 09:13:28 +05:30
|
|
|
function ensureModelConfig() {
|
|
|
|
|
const configPath = path.join(WorkDir, "config", "models.json");
|
|
|
|
|
if (!fs.existsSync(configPath)) {
|
|
|
|
|
fs.writeFileSync(configPath, JSON.stringify(baseModelConfig, null, 2));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-10-30 16:09:19 +08:00
|
|
|
function ensureDirs() {
|
|
|
|
|
const ensure = (p: string) => { if (!fs.existsSync(p)) fs.mkdirSync(p, { recursive: true }); };
|
|
|
|
|
ensure(WorkDir);
|
|
|
|
|
ensure(path.join(WorkDir, "workflows"));
|
|
|
|
|
ensure(path.join(WorkDir, "agents"));
|
2025-11-07 11:42:10 +05:30
|
|
|
ensure(path.join(WorkDir, "config"));
|
|
|
|
|
ensureMcpConfig();
|
2025-11-14 09:13:28 +05:30
|
|
|
ensureModelConfig();
|
2025-10-30 16:09:19 +08:00
|
|
|
}
|
2025-10-28 13:17:06 +05:30
|
|
|
|
2025-11-05 13:28:38 +05:30
|
|
|
ensureDirs();
|
|
|
|
|
|
2025-10-28 13:17:06 +05:30
|
|
|
function loadMcpServerConfig(): z.infer<typeof McpServerConfig> {
|
2025-11-07 11:42:10 +05:30
|
|
|
const configPath = path.join(WorkDir, "config", "mcp.json");
|
|
|
|
|
if (!fs.existsSync(configPath)) return { mcpServers: {} };
|
2025-10-28 13:17:06 +05:30
|
|
|
const config = fs.readFileSync(configPath, "utf8");
|
|
|
|
|
return McpServerConfig.parse(JSON.parse(config));
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-14 09:23:37 +05:30
|
|
|
function loadModelConfig(): z.infer<typeof ModelConfigT> {
|
2025-11-14 09:13:28 +05:30
|
|
|
const configPath = path.join(WorkDir, "config", "models.json");
|
|
|
|
|
if (!fs.existsSync(configPath)) return baseModelConfig;
|
|
|
|
|
const config = fs.readFileSync(configPath, "utf8");
|
2025-11-14 09:23:37 +05:30
|
|
|
return ModelConfigT.parse(JSON.parse(config));
|
2025-11-14 09:13:28 +05:30
|
|
|
}
|
|
|
|
|
|
2025-10-28 13:17:06 +05:30
|
|
|
const { mcpServers } = loadMcpServerConfig();
|
2025-10-30 16:09:19 +08:00
|
|
|
export const McpServers = mcpServers;
|
2025-11-14 09:23:37 +05:30
|
|
|
export const ModelConfig = loadModelConfig();
|