mirror of
https://github.com/pbakaus/impeccable.git
synced 2026-09-11 21:57:14 +03:00
The public repo keeps the OSS promise surface: skill, CLI, extension, tests, and the provider build. The site, labs, concept/composition catalogs, image pipeline, Cloudflare functions, and authoring guide move to pbakaus/impeccable-site. concept-seed tests run against a synthetic fixture catalog; the plugin icon and skill categories moved in-repo; build validation narrows to README prose and non-site counts; release notes read from a sibling impeccable-site checkout. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
62 lines
2.1 KiB
JavaScript
62 lines
2.1 KiB
JavaScript
import fs from 'fs';
|
|
import path from 'path';
|
|
|
|
import { buildCodexPluginManifest } from './codex-plugin.js';
|
|
import { buildCodexPluginHooksManifest } from './transformers/hooks.js';
|
|
|
|
function requirePath(absPath, label) {
|
|
if (!fs.existsSync(absPath)) {
|
|
throw new Error(`Cannot build OpenAI plugin: missing ${label}: ${absPath}`);
|
|
}
|
|
}
|
|
|
|
function writeJson(absPath, value) {
|
|
fs.mkdirSync(path.dirname(absPath), { recursive: true });
|
|
fs.writeFileSync(absPath, `${JSON.stringify(value, null, 2)}\n`);
|
|
}
|
|
|
|
/**
|
|
* Stage the public OpenAI plugin from the Codex-transformed skill payload.
|
|
*
|
|
* The tracked ./plugin subtree is a Claude Code marketplace artifact. Reusing
|
|
* its shared skills/ directory here silently ships Claude paths and slash
|
|
* commands inside a Codex plugin. Keep this stage independent so each plugin
|
|
* receives the provider transform it was built for.
|
|
*/
|
|
export function stageOpenAIPlugin(rootDir, distDir) {
|
|
const rootManifestPath = path.join(rootDir, '.claude-plugin', 'plugin.json');
|
|
const codexSkillSrc = path.join(distDir, 'codex', '.codex', 'skills', 'impeccable');
|
|
const iconSrc = path.join(rootDir, 'scripts', 'lib', 'assets', 'plugin-icon.png');
|
|
|
|
requirePath(rootManifestPath, 'root plugin manifest');
|
|
requirePath(codexSkillSrc, 'Codex skill payload');
|
|
requirePath(iconSrc, 'plugin icon');
|
|
|
|
const pluginRoot = path.join(distDir, 'openai', 'impeccable');
|
|
fs.rmSync(pluginRoot, { recursive: true, force: true });
|
|
fs.mkdirSync(pluginRoot, { recursive: true });
|
|
|
|
const rootManifest = JSON.parse(fs.readFileSync(rootManifestPath, 'utf8'));
|
|
writeJson(
|
|
path.join(pluginRoot, '.codex-plugin', 'plugin.json'),
|
|
buildCodexPluginManifest(rootManifest),
|
|
);
|
|
|
|
fs.mkdirSync(path.join(pluginRoot, 'assets'), { recursive: true });
|
|
fs.copyFileSync(iconSrc, path.join(pluginRoot, 'assets', 'icon.png'));
|
|
|
|
fs.mkdirSync(path.join(pluginRoot, 'skills'), { recursive: true });
|
|
fs.cpSync(
|
|
codexSkillSrc,
|
|
path.join(pluginRoot, 'skills', 'impeccable'),
|
|
{ recursive: true },
|
|
);
|
|
|
|
writeJson(
|
|
path.join(pluginRoot, 'hooks', 'hooks.json'),
|
|
buildCodexPluginHooksManifest(),
|
|
);
|
|
|
|
return pluginRoot;
|
|
}
|