|
|
@@ -1,6 +1,8 @@
|
|
|
// 服务容器:组装数据库、各个 service 与引擎
|
|
|
+import fs from 'node:fs'
|
|
|
+import path from 'node:path'
|
|
|
import type { ProviderId } from '@agent-server/shared'
|
|
|
-import { config, dbPath } from './config'
|
|
|
+import { communitySkillsDir, config, customSkillsDir, dbPath } from './config'
|
|
|
import { createDb, migrateDb, type DB } from './db'
|
|
|
import { ClaudeProvider } from './providers/claude/adapter'
|
|
|
import { CodexProvider } from './providers/codex/adapter'
|
|
|
@@ -52,6 +54,7 @@ export function createApp(log: AppLogger, opts: { db?: DB; providers?: Partial<R
|
|
|
const mcpUpstream = new McpUpstream()
|
|
|
const mcpServers = new McpServerService(db, mcpUpstream, () => settings.get(), summary => audit.log({ actor: 'admin', kind: 'admin', summary }))
|
|
|
const adminAudit = (summary: string, detail?: unknown) => audit.log({ actor: 'admin', kind: 'admin', summary, detail })
|
|
|
+ migrateManagedSkillDirs(log)
|
|
|
const customSkills = new CustomSkillService(db, adminAudit)
|
|
|
// 按数据库重建生效目录(缺失或被改动的技能目录重新发布)
|
|
|
customSkills.reconcile(msg => log.warn({}, msg))
|
|
|
@@ -77,3 +80,21 @@ export function createApp(log: AppLogger, opts: { db?: DB; providers?: Partial<R
|
|
|
}
|
|
|
|
|
|
export type App = ReturnType<typeof createApp>
|
|
|
+
|
|
|
+/** 技能生效目录从 data/ 下移到顶层 managed-skills/ 后,一次性搬走旧目录(同一文件系统,直接改名) */
|
|
|
+function migrateManagedSkillDirs(log: AppLogger) {
|
|
|
+ const moves: [string, string][] = [
|
|
|
+ [path.join(config.dataDir, 'data', 'community-skills'), communitySkillsDir()],
|
|
|
+ [path.join(config.dataDir, 'data', 'custom-skills'), customSkillsDir()],
|
|
|
+ ]
|
|
|
+ for (const [from, to] of moves) {
|
|
|
+ if (!fs.existsSync(from)) continue
|
|
|
+ if (fs.existsSync(to)) {
|
|
|
+ log.warn({ from, to }, '旧的技能目录仍然存在,新目录已有内容,保留旧目录不处理')
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ fs.mkdirSync(path.dirname(to), { recursive: true })
|
|
|
+ fs.renameSync(from, to)
|
|
|
+ log.info({ from, to }, '技能目录已迁移')
|
|
|
+ }
|
|
|
+}
|