mirror of
https://github.com/pbakaus/impeccable.git
synced 2026-09-12 14:16:28 +03:00
Build a Codex-native OpenAI plugin with bundled hooks, public listing metadata, submission guidance, privacy coverage, and regression tests. AI assistance: OpenAI Codex prepared and validated these changes under maintainer direction.
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, 'site', 'public', 'apple-touch-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;
|
|
}
|