收口 Makelore 客户端变更
Some checks failed
Electron E2E / Electron E2E (macos-latest) (push) Has been cancelled
Electron E2E / Electron E2E (ubuntu-latest) (push) Has been cancelled
Electron E2E / Electron E2E (windows-latest) (push) Has been cancelled

This commit is contained in:
inman
2026-08-12 22:35:06 +08:00
parent 253bad8b40
commit f4113a872f
232 changed files with 4617 additions and 20121 deletions

View File

@@ -0,0 +1,112 @@
import {
cpSync,
existsSync,
lstatSync,
mkdirSync,
rmSync,
unlinkSync,
} from 'node:fs';
import { join } from 'node:path';
export interface BundledSkillsPathInput {
isPackaged: boolean;
resourcesPath: string;
appPath: string;
}
export interface EnsureBundledCourseSkillsOptions {
managedConfigDir: string;
sourceDir?: string;
}
export const BUNDLED_COURSE_SKILL_IDS = [
'agent-browser',
'deploy-publish-check',
'designer-design-spec',
'dev-build-test',
'game-assets',
'marketing-launch-story',
'nianxxgame-skill',
'partner-agent-showcase',
'pm-project-plan',
'product-demo-prototype',
'ui-ux-course-quality',
'youth-plain-language',
'youth-ai-product-course',
] as const;
const RETIRED_COURSE_SKILL_IDS = ['course-stage-review', 'student-growth-logger'] as const;
const LEGACY_SUPERPOWERS_ARTIFACTS = [
'plugins/superpowers-niancode.js',
'plugins/superpowers.js',
'superpowers-active.json',
'superpowers-bundles',
] as const;
export function resolveBundledCourseSkillsDir(input: BundledSkillsPathInput): string {
return input.isPackaged
? join(input.resourcesPath, 'course-skills')
: join(input.appPath, '.opencode', 'skills');
}
export function resolveBundledAgentBrowserPluginPath(input: BundledSkillsPathInput): string {
return join(
resolveBundledCourseSkillsDir(input),
'agent-browser',
'.opencode',
'plugins',
'niancode-agent-browser.js',
);
}
export function getManagedOpencodeConfigDir(userDataDir: string): string {
return join(userDataDir, 'opencode', 'niancode-config');
}
function copyDirectorySync(sourceDir: string, targetDir: string): void {
cpSync(sourceDir, targetDir, {
recursive: true,
force: true,
filter: (sourcePath, targetPath) => {
// Node 24.14's Windows override path can corrupt non-ASCII destinations
// when replacing a file. Public unlink keeps force-overwrite semantics.
if (lstatSync(sourcePath).isFile() && existsSync(targetPath)) {
unlinkSync(targetPath);
}
return true;
},
});
}
export function removeLegacySuperpowersArtifacts(managedConfigDir: string): void {
for (const artifact of LEGACY_SUPERPOWERS_ARTIFACTS) {
rmSync(join(managedConfigDir, artifact), { recursive: true, force: true });
}
}
export function ensureBundledCourseSkills(options: EnsureBundledCourseSkillsOptions): boolean {
const sourceDir = options.sourceDir?.trim();
if (!sourceDir || !existsSync(sourceDir)) {
return false;
}
const targetSkillsDir = join(options.managedConfigDir, 'skills');
mkdirSync(targetSkillsDir, { recursive: true });
for (const skillId of RETIRED_COURSE_SKILL_IDS) {
rmSync(join(targetSkillsDir, skillId), { recursive: true, force: true });
}
copyDirectorySync(sourceDir, targetSkillsDir);
return true;
}
export function ensureBundledAgentBrowserPlugin(options: {
managedConfigDir: string;
sourcePath?: string;
}): boolean {
const sourcePath = options.sourcePath?.trim();
if (!sourcePath || !existsSync(sourcePath)) return false;
const targetPluginsDir = join(options.managedConfigDir, 'plugins');
mkdirSync(targetPluginsDir, { recursive: true });
cpSync(sourcePath, join(targetPluginsDir, 'niancode-agent-browser.js'), { force: true });
return true;
}