mirror of
https://github.com/pbakaus/impeccable.git
synced 2026-09-12 06:06:37 +03:00
Merge main and integrate command_prefix support into factory
Resolve conflict from codex.js (deleted in our branch, modified on main for command_prefix). The command_prefix feature from main is preserved in factory.js via PROVIDER_PLACEHOLDERS lookup. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -67,7 +67,7 @@ For each issue, document:
|
||||
- **Impact**: How it affects users
|
||||
- **WCAG/Standard**: Which standard it violates (if applicable)
|
||||
- **Recommendation**: How to fix it
|
||||
- **Suggested command**: Which command to use (prefer: /animate, /quieter, /optimize, /adapt, /clarify, /distill, /delight, /onboard, /normalize, /audit, /harden, /polish, /extract, /bolder, /arrange, /typeset, /critique, /colorize, /overdrive — or other installed skills you're sure exist)
|
||||
- **Suggested command**: Which command to use (prefer: $animate, $quieter, $optimize, $adapt, $clarify, $distill, $delight, $onboard, $normalize, $audit, $harden, $polish, $extract, $bolder, $arrange, $typeset, $critique, $colorize, $overdrive — or other installed skills you're sure exist)
|
||||
|
||||
#### Critical Issues
|
||||
[Issues that block core functionality or violate WCAG A]
|
||||
@@ -104,12 +104,12 @@ Create actionable plan:
|
||||
|
||||
### Suggested Commands for Fixes
|
||||
|
||||
Map issues to available commands. Prefer these: /animate, /quieter, /optimize, /adapt, /clarify, /distill, /delight, /onboard, /normalize, /audit, /harden, /polish, /extract, /bolder, /arrange, /typeset, /critique, /colorize, /overdrive. You may also suggest other installed skills you're sure exist, but never invent commands.
|
||||
Map issues to available commands. Prefer these: $animate, $quieter, $optimize, $adapt, $clarify, $distill, $delight, $onboard, $normalize, $audit, $harden, $polish, $extract, $bolder, $arrange, $typeset, $critique, $colorize, $overdrive. You may also suggest other installed skills you're sure exist, but never invent commands.
|
||||
|
||||
Examples:
|
||||
- "Use `/normalize` to align with design system (addresses N theming issues)"
|
||||
- "Use `/optimize` to improve performance (addresses N performance issues)"
|
||||
- "Use `/harden` to improve resilience (addresses N edge cases)"
|
||||
- "Use `$normalize` to align with design system (addresses N theming issues)"
|
||||
- "Use `$optimize` to improve performance (addresses N performance issues)"
|
||||
- "Use `$harden` to improve resilience (addresses N edge cases)"
|
||||
|
||||
**IMPORTANT**: Be thorough but actionable. Too many low-priority issues creates noise. Focus on what actually matters.
|
||||
|
||||
|
||||
@@ -98,7 +98,7 @@ For each issue:
|
||||
- **What**: Name the problem clearly
|
||||
- **Why it matters**: How this hurts users or undermines goals
|
||||
- **Fix**: What to do about it (be concrete)
|
||||
- **Command**: Which command to use (prefer: /animate, /quieter, /optimize, /adapt, /clarify, /distill, /delight, /onboard, /normalize, /audit, /harden, /polish, /extract, /bolder, /arrange, /typeset, /critique, /colorize, /overdrive — or other installed skills you're sure exist)
|
||||
- **Command**: Which command to use (prefer: $animate, $quieter, $optimize, $adapt, $clarify, $distill, $delight, $onboard, $normalize, $audit, $harden, $polish, $extract, $bolder, $arrange, $typeset, $critique, $colorize, $overdrive — or other installed skills you're sure exist)
|
||||
|
||||
### Minor Observations
|
||||
Quick notes on smaller issues worth addressing.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import path from 'path';
|
||||
import { cleanDir, ensureDir, writeFile, generateYamlFrontmatter, replacePlaceholders, prefixSkillReferences } from '../utils.js';
|
||||
import { cleanDir, ensureDir, writeFile, generateYamlFrontmatter, replacePlaceholders, prefixSkillReferences, PROVIDER_PLACEHOLDERS } from '../utils.js';
|
||||
|
||||
/**
|
||||
* Map from frontmatter field name to extraction spec.
|
||||
@@ -86,8 +86,9 @@ export function createTransformer(config) {
|
||||
const frontmatter = generateYamlFrontmatter(frontmatterObj);
|
||||
|
||||
// Build body
|
||||
let skillBody = replacePlaceholders(skill.body, provider, commandNames);
|
||||
if (prefix) skillBody = prefixSkillReferences(skillBody, prefix, allSkillNames);
|
||||
const cmdPrefix = (PROVIDER_PLACEHOLDERS[provider] || {}).command_prefix || '/';
|
||||
let skillBody = replacePlaceholders(skill.body, provider, commandNames, allSkillNames);
|
||||
if (prefix) skillBody = prefixSkillReferences(skillBody, prefix, allSkillNames, cmdPrefix);
|
||||
if (bodyTransform) skillBody = bodyTransform(skillBody, skill);
|
||||
|
||||
const content = `${frontmatter}\n\n${skillBody}`;
|
||||
@@ -98,7 +99,7 @@ export function createTransformer(config) {
|
||||
const refDir = path.join(skillDir, 'reference');
|
||||
ensureDir(refDir);
|
||||
for (const ref of skill.references) {
|
||||
const refContent = replacePlaceholders(ref.content, provider);
|
||||
const refContent = replacePlaceholders(ref.content, provider, [], allSkillNames);
|
||||
writeFile(path.join(refDir, `${ref.name}.md`), refContent);
|
||||
refCount++;
|
||||
}
|
||||
|
||||
+42
-13
@@ -271,42 +271,50 @@ export const PROVIDER_PLACEHOLDERS = {
|
||||
'claude-code': {
|
||||
model: 'Claude',
|
||||
config_file: 'CLAUDE.md',
|
||||
ask_instruction: 'STOP and call the AskUserQuestion tool to clarify.'
|
||||
ask_instruction: 'STOP and call the AskUserQuestion tool to clarify.',
|
||||
command_prefix: '/'
|
||||
},
|
||||
'cursor': {
|
||||
model: 'the model',
|
||||
config_file: '.cursorrules',
|
||||
ask_instruction: 'ask the user directly to clarify what you cannot infer.'
|
||||
ask_instruction: 'ask the user directly to clarify what you cannot infer.',
|
||||
command_prefix: '/'
|
||||
},
|
||||
'gemini': {
|
||||
model: 'Gemini',
|
||||
config_file: 'GEMINI.md',
|
||||
ask_instruction: 'ask the user directly to clarify what you cannot infer.'
|
||||
ask_instruction: 'ask the user directly to clarify what you cannot infer.',
|
||||
command_prefix: '/'
|
||||
},
|
||||
'codex': {
|
||||
model: 'GPT',
|
||||
config_file: 'AGENTS.md',
|
||||
ask_instruction: 'ask the user directly to clarify what you cannot infer.'
|
||||
ask_instruction: 'ask the user directly to clarify what you cannot infer.',
|
||||
command_prefix: '$'
|
||||
},
|
||||
'agents': {
|
||||
model: 'the model',
|
||||
config_file: '.github/copilot-instructions.md',
|
||||
ask_instruction: 'ask the user directly to clarify what you cannot infer.'
|
||||
ask_instruction: 'ask the user directly to clarify what you cannot infer.',
|
||||
command_prefix: '/'
|
||||
},
|
||||
'kiro': {
|
||||
model: 'Claude',
|
||||
config_file: '.kiro/settings.json',
|
||||
ask_instruction: 'ask the user directly to clarify what you cannot infer.'
|
||||
ask_instruction: 'ask the user directly to clarify what you cannot infer.',
|
||||
command_prefix: '/'
|
||||
},
|
||||
opencode: {
|
||||
model: 'Claude',
|
||||
config_file: 'AGENTS.md',
|
||||
ask_instruction: 'STOP and call the `question` tool to clarify.',
|
||||
command_prefix: '/'
|
||||
},
|
||||
'pi': {
|
||||
model: 'the model',
|
||||
config_file: 'AGENTS.md',
|
||||
ask_instruction: 'ask the user directly to clarify what you cannot infer.'
|
||||
ask_instruction: 'ask the user directly to clarify what you cannot infer.',
|
||||
command_prefix: '/'
|
||||
}
|
||||
};
|
||||
|
||||
@@ -320,8 +328,9 @@ export const PROVIDER_PLACEHOLDERS = {
|
||||
* @param {string} content - The skill body text
|
||||
* @param {string} prefix - The prefix to add (e.g., 'i-')
|
||||
* @param {string[]} skillNames - Array of all skill names
|
||||
* @param {string} commandPrefix - The command invocation prefix (e.g., '/' or '$')
|
||||
*/
|
||||
export function prefixSkillReferences(content, prefix, skillNames) {
|
||||
export function prefixSkillReferences(content, prefix, skillNames, commandPrefix = '/') {
|
||||
if (!prefix || !skillNames || skillNames.length === 0) return content;
|
||||
|
||||
let result = content;
|
||||
@@ -331,8 +340,12 @@ export function prefixSkillReferences(content, prefix, skillNames) {
|
||||
for (const name of sorted) {
|
||||
const prefixed = `${prefix}${name}`;
|
||||
|
||||
// Replace `/skillname` references (command invocations)
|
||||
result = result.replace(new RegExp(`\\/(?=${escapeRegex(name)}(?:[^a-zA-Z0-9_-]|$))`, 'g'), `/${prefix}`);
|
||||
// Replace command invocations (e.g., `/skillname` or `$skillname`) with prefixed versions
|
||||
const escapedPrefix = escapeRegex(commandPrefix);
|
||||
result = result.replace(
|
||||
new RegExp(`${escapedPrefix}(?=${escapeRegex(name)}(?:[^a-zA-Z0-9_-]|$))`, 'g'),
|
||||
`${commandPrefix}${prefix}`
|
||||
);
|
||||
|
||||
// Replace `the skillname skill` references
|
||||
result = result.replace(
|
||||
@@ -350,18 +363,34 @@ function escapeRegex(str) {
|
||||
|
||||
const EXCLUDED_FROM_SUGGESTIONS = new Set(['teach-impeccable', 'i-teach-impeccable']);
|
||||
|
||||
export function replacePlaceholders(content, provider, commandNames = []) {
|
||||
export function replacePlaceholders(content, provider, commandNames = [], allSkillNames = []) {
|
||||
const placeholders = PROVIDER_PLACEHOLDERS[provider] || PROVIDER_PLACEHOLDERS['cursor'];
|
||||
const cmdPrefix = placeholders.command_prefix || '/';
|
||||
const commandList = commandNames
|
||||
.filter(n => !EXCLUDED_FROM_SUGGESTIONS.has(n))
|
||||
.map(n => `/${n}`)
|
||||
.map(n => `${cmdPrefix}${n}`)
|
||||
.join(', ');
|
||||
|
||||
return content
|
||||
let result = content
|
||||
.replace(/\{\{model\}\}/g, placeholders.model)
|
||||
.replace(/\{\{config_file\}\}/g, placeholders.config_file)
|
||||
.replace(/\{\{ask_instruction\}\}/g, placeholders.ask_instruction)
|
||||
.replace(/\{\{command_prefix\}\}/g, cmdPrefix)
|
||||
.replace(/\{\{available_commands\}\}/g, commandList);
|
||||
|
||||
// Replace `/skillname` invocations with the correct command prefix for this provider
|
||||
// (e.g., `/normalize` → `$normalize` for Codex)
|
||||
if (cmdPrefix !== '/' && allSkillNames.length > 0) {
|
||||
const sorted = [...allSkillNames].sort((a, b) => b.length - a.length);
|
||||
for (const name of sorted) {
|
||||
result = result.replace(
|
||||
new RegExp(`\\/(?=${escapeRegex(name)}(?:[^a-zA-Z0-9_-]|$))`, 'g'),
|
||||
cmdPrefix
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user