Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion ui/desktop/forge.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const isLinuxVulkanBuild = process.env.GOOSE_DESKTOP_LINUX_VARIANT === 'vulkan';
let cfg = {
asar: true,
executableName: 'Goose',
extraResource: ['src/bin', 'src/images'],
extraResource: ['src/bin', 'src/images', 'default-recipes'],
icon: 'src/images/icon',
// Windows specific configuration
win32: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,5 +52,19 @@
"type": "builtin",
"env_keys": [],
"bundled": true
},
{
"id": "apemind",
"name": "apemind",
"display_name": "ApeMind",
"description": "ApeMind 知识图谱 / RAG 服务(启用前请在扩展设置里替换 URL 与 Authorization Bearer token)",
"enabled": false,
"type": "streamable_http",
"uri": "https://your-apemind.example.com/mcp",
"headers": {
"Authorization": "Bearer your-api-key-here"
},
"timeout": 300,
"bundled": true
}
]
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ type BundledExtension = {
uri?: string;
envs?: { [key: string]: string };
env_keys?: Array<string>;
headers?: { [key: string]: string };
timeout?: number;
allow_configure?: boolean;
};
Expand Down Expand Up @@ -116,6 +117,9 @@ export async function syncBundledExtensions(
description: bundledExt.description,
timeout: bundledExt.timeout,
uri: bundledExt.uri || '',
envs: bundledExt.envs,
env_keys: bundledExt.env_keys || [],
headers: bundledExt.headers,
bundled: true,
};
}
Expand Down
25 changes: 25 additions & 0 deletions ui/desktop/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,25 @@ function translateMenuLabels(items: MenuItem[]): void {
const SETTINGS_FILE = path.join(app.getPath('userData'), 'settings.json');
const STARTUP_LOGS_DIR = path.join(app.getPath('userData'), 'logs', 'startup');

async function seedDefaultRecipes(): Promise<void> {
const sourceRoot = app.isPackaged
? path.join(process.resourcesPath, 'default-recipes')
: path.join(__dirname, '..', 'default-recipes');
const destDir = path.join(os.homedir(), '.config', 'goose', 'recipes');

if (!fsSync.existsSync(sourceRoot)) return;

await fs.mkdir(destDir, { recursive: true });
const entries = await fs.readdir(sourceRoot);
for (const entry of entries) {
if (!entry.endsWith('.yaml') && !entry.endsWith('.yml')) continue;
const destPath = path.join(destDir, entry);
if (fsSync.existsSync(destPath)) continue;
await fs.copyFile(path.join(sourceRoot, entry), destPath);
log.info(`[seedDefaultRecipes] seeded ${entry} → ${destPath}`);
}
}

function getSettings(): Settings {
if (fsSync.existsSync(SETTINGS_FILE)) {
let stored: Partial<Settings>;
Expand Down Expand Up @@ -2079,6 +2098,12 @@ const registerGlobalShortcuts = () => {
async function appMain() {
await configureProxy();

try {
await seedDefaultRecipes();
} catch (err) {
log.warn('[seedDefaultRecipes] failed:', err);
}

// Ensure Windows shims are available before any MCP processes are spawned
await ensureWinShims();

Expand Down
Loading