mirror of
https://github.com/pbakaus/impeccable.git
synced 2026-09-12 06:06:37 +03:00
* Add OpenAI plugin submission bundle 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. * Fix provider script command rendering Replace heuristic rewrites across executable scripts with one explicit provider marker, render pinned shortcuts per target harness, and remove the personal email from the public publisher manifest. Addresses automated review feedback on PR #363. AI assistance: OpenAI Codex prepared and validated these changes under maintainer direction.
95 lines
3.5 KiB
JavaScript
95 lines
3.5 KiB
JavaScript
import { afterEach, beforeEach, describe, it } from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import fs from 'node:fs';
|
|
import os from 'node:os';
|
|
import path from 'node:path';
|
|
|
|
import { stageOpenAIPlugin } from '../scripts/lib/openai-plugin.js';
|
|
import { buildCodexPluginHooksManifest } from '../scripts/lib/transformers/hooks.js';
|
|
|
|
function write(root, rel, contents) {
|
|
const abs = path.join(root, rel);
|
|
fs.mkdirSync(path.dirname(abs), { recursive: true });
|
|
fs.writeFileSync(abs, contents);
|
|
}
|
|
|
|
describe('OpenAI plugin staging', () => {
|
|
let root;
|
|
let dist;
|
|
|
|
beforeEach(() => {
|
|
root = fs.mkdtempSync(path.join(os.tmpdir(), 'impeccable-openai-plugin-'));
|
|
dist = path.join(root, 'dist');
|
|
|
|
write(root, '.claude-plugin/plugin.json', JSON.stringify({
|
|
name: 'impeccable',
|
|
version: '3.9.1',
|
|
author: {
|
|
name: 'Paul Bakaus',
|
|
email: 'paul@example.com',
|
|
},
|
|
homepage: 'https://impeccable.style',
|
|
repository: 'https://github.com/pbakaus/impeccable',
|
|
}));
|
|
write(root, 'site/public/apple-touch-icon.png', 'icon');
|
|
|
|
write(
|
|
root,
|
|
'dist/codex/.codex/skills/impeccable/SKILL.md',
|
|
'---\nname: impeccable\n---\n\nUse $impeccable. Run .codex/skills/impeccable/scripts/context.mjs.\n',
|
|
);
|
|
write(
|
|
root,
|
|
'dist/codex/.codex/skills/impeccable/agents/openai.yaml',
|
|
'interface:\n display_name: Impeccable\n',
|
|
);
|
|
write(
|
|
root,
|
|
'dist/codex/.codex/skills/impeccable/agents/impeccable_asset_producer.toml',
|
|
'name = "impeccable_asset_producer"\n',
|
|
);
|
|
|
|
// A Claude payload exists too. The OpenAI stage must never read it.
|
|
write(
|
|
root,
|
|
'dist/claude-code/.claude/skills/impeccable/SKILL.md',
|
|
'---\nname: impeccable\n---\n\nUse /impeccable. Run .claude/skills/impeccable/scripts/context.mjs.\n',
|
|
);
|
|
});
|
|
|
|
afterEach(() => {
|
|
fs.rmSync(root, { recursive: true, force: true });
|
|
});
|
|
|
|
it('packages the Codex skill, agents, manifest, icon, and compatible hook', () => {
|
|
const pluginRoot = stageOpenAIPlugin(root, dist);
|
|
const skill = fs.readFileSync(path.join(pluginRoot, 'skills/impeccable/SKILL.md'), 'utf8');
|
|
const manifest = JSON.parse(fs.readFileSync(path.join(pluginRoot, '.codex-plugin/plugin.json'), 'utf8'));
|
|
const hooks = JSON.parse(fs.readFileSync(path.join(pluginRoot, 'hooks/hooks.json'), 'utf8'));
|
|
|
|
assert.match(skill, /\$impeccable/);
|
|
assert.match(skill, /\.codex\/skills\/impeccable/);
|
|
assert.doesNotMatch(skill, /(?:^|[\s`(])\/impeccable\b/m);
|
|
assert.doesNotMatch(skill, /\.claude\/skills\/impeccable/);
|
|
|
|
assert.ok(fs.existsSync(path.join(pluginRoot, 'skills/impeccable/agents/openai.yaml')));
|
|
assert.ok(fs.existsSync(path.join(
|
|
pluginRoot,
|
|
'skills/impeccable/agents/impeccable_asset_producer.toml',
|
|
)));
|
|
assert.ok(fs.existsSync(path.join(pluginRoot, 'assets/icon.png')));
|
|
|
|
assert.equal(manifest.skills, './skills/');
|
|
assert.deepEqual(manifest.author, {
|
|
name: 'Renaissance Geek Inc',
|
|
url: 'https://impeccable.style',
|
|
});
|
|
assert.equal('email' in manifest.author, false);
|
|
assert.equal(manifest.interface.shortDescription, 'Design and refine interfaces');
|
|
assert.equal(manifest.interface.category, 'Creativity');
|
|
assert.deepEqual(hooks, buildCodexPluginHooksManifest());
|
|
assert.match(hooks.hooks.PostToolUse[0].hooks[0].command, /\$\{PLUGIN_ROOT\}/);
|
|
assert.doesNotMatch(hooks.hooks.PostToolUse[0].hooks[0].command, /CLAUDE_PLUGIN_ROOT/);
|
|
});
|
|
});
|