mirror of
https://github.com/affaan-m/ECC.git
synced 2026-09-29 04:55:12 +02:00
Merge reviewed contributor PR #3060 into backlog batch
Source-PR: https://github.com/affaan-m/ECC/pull/3060
Source-Head: f8c604d37e
Local integration checkpoint; aggregate review and hosted acceptance pending.
This commit is contained in:
+1
-1
@@ -4,7 +4,7 @@ This file provides Gemini CLI with the baseline ECC workflow, review standards,
|
||||
|
||||
## Overview
|
||||
|
||||
Everything Claude Code (ECC) is a cross-harness coding system with 36 specialized agents, 142 skills, and 68 commands.
|
||||
Everything Claude Code (ECC) is a cross-harness coding system with 68 specialized agents, 292 skills, and 94 commands.
|
||||
|
||||
Gemini support is currently focused on a strong project-local instruction layer via `.gemini/GEMINI.md`, plus the shared MCP catalog and package-manager setup assets shipped by the installer.
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Soul
|
||||
|
||||
## Core Identity
|
||||
Everything Claude Code (ECC) is a production-ready AI coding plugin: specialized agents, on-demand skills, slash commands, rules, and automated hook workflows for software development.
|
||||
Everything Claude Code (ECC) is a production-ready AI coding plugin with 68 specialized agents, 292 skills, 94 commands, and automated hook workflows for software development.
|
||||
|
||||
## Core Principles
|
||||
1. **Agent-First** — route work to the right specialist as early as possible.
|
||||
|
||||
@@ -18,6 +18,8 @@ const path = require('path');
|
||||
const ROOT = path.join(__dirname, '../..');
|
||||
const README_PATH = path.join(ROOT, 'README.md');
|
||||
const AGENTS_PATH = path.join(ROOT, 'AGENTS.md');
|
||||
const SOUL_PATH = path.join(ROOT, 'SOUL.md');
|
||||
const GEMINI_PATH = path.join(ROOT, '.gemini', 'GEMINI.md');
|
||||
const README_ZH_CN_PATH = path.join(ROOT, 'README.zh-CN.md');
|
||||
const DOCS_ZH_CN_README_PATH = path.join(ROOT, 'docs', 'zh-CN', 'README.md');
|
||||
const DOCS_ZH_CN_AGENTS_PATH = path.join(ROOT, 'docs', 'zh-CN', 'AGENTS.md');
|
||||
@@ -273,6 +275,30 @@ function parseAgentsDocExpectations(agentsContent) {
|
||||
return expectations;
|
||||
}
|
||||
|
||||
function parseCrossHarnessIdentityExpectations(content, source) {
|
||||
const match = content.match(/with\s+(\d+)\s+specialized agents,\s+(\d+)\s+skills,\s+(?:and\s+)?(\d+)\s+commands/i);
|
||||
if (!match) {
|
||||
throw new Error(`${source} is missing the catalog summary line`);
|
||||
}
|
||||
|
||||
return [
|
||||
{ category: 'agents', mode: 'exact', expected: Number(match[1]), source },
|
||||
{ category: 'skills', mode: 'exact', expected: Number(match[2]), source },
|
||||
{ category: 'commands', mode: 'exact', expected: Number(match[3]), source },
|
||||
];
|
||||
}
|
||||
|
||||
function syncCrossHarnessIdentity(content, catalog, source) {
|
||||
return replaceOrThrow(
|
||||
content,
|
||||
/(with\s+)(\d+)(\s+specialized agents,\s+)(\d+)(\s+skills,\s+(?:and\s+)?)(\d+)(\s+commands)/i,
|
||||
(_, prefix, __, agentsSuffix, ___, skillsSuffix, ____, commandsSuffix) => (
|
||||
`${prefix}${catalog.agents.count}${agentsSuffix}${catalog.skills.count}${skillsSuffix}${catalog.commands.count}${commandsSuffix}`
|
||||
),
|
||||
source
|
||||
);
|
||||
}
|
||||
|
||||
function parseZhAgentsDocExpectations(agentsContent) {
|
||||
const summaryMatch = agentsContent.match(/提供\s+(\d+)\s+个专业代理、\s*(\d+)(\+)?\s*项技能、\s*(\d+)\s+条命令/i);
|
||||
if (!summaryMatch) {
|
||||
@@ -563,6 +589,8 @@ function createDocumentSpecs(paths = {}) {
|
||||
const {
|
||||
readmePath = README_PATH,
|
||||
agentsPath = AGENTS_PATH,
|
||||
soulPath = SOUL_PATH,
|
||||
geminiPath = GEMINI_PATH,
|
||||
zhRootReadmePath = README_ZH_CN_PATH,
|
||||
zhDocsReadmePath = DOCS_ZH_CN_README_PATH,
|
||||
zhDocsAgentsPath = DOCS_ZH_CN_AGENTS_PATH,
|
||||
@@ -581,6 +609,16 @@ function createDocumentSpecs(paths = {}) {
|
||||
parseExpectations: parseAgentsDocExpectations,
|
||||
syncContent: syncEnglishAgents,
|
||||
},
|
||||
{
|
||||
filePath: soulPath,
|
||||
parseExpectations: content => parseCrossHarnessIdentityExpectations(content, 'SOUL.md'),
|
||||
syncContent: (content, catalog) => syncCrossHarnessIdentity(content, catalog, 'SOUL.md'),
|
||||
},
|
||||
{
|
||||
filePath: geminiPath,
|
||||
parseExpectations: content => parseCrossHarnessIdentityExpectations(content, '.gemini/GEMINI.md'),
|
||||
syncContent: (content, catalog) => syncCrossHarnessIdentity(content, catalog, '.gemini/GEMINI.md'),
|
||||
},
|
||||
{
|
||||
filePath: zhRootReadmePath,
|
||||
parseExpectations: parseZhRootReadmeExpectations,
|
||||
@@ -633,6 +671,8 @@ function createDocumentSpecsForRoot(root) {
|
||||
return createDocumentSpecs({
|
||||
readmePath: path.join(root, 'README.md'),
|
||||
agentsPath: path.join(root, 'AGENTS.md'),
|
||||
soulPath: path.join(root, 'SOUL.md'),
|
||||
geminiPath: path.join(root, '.gemini', 'GEMINI.md'),
|
||||
zhRootReadmePath: path.join(root, 'README.zh-CN.md'),
|
||||
zhDocsReadmePath: path.join(root, 'docs', 'zh-CN', 'README.md'),
|
||||
zhDocsAgentsPath: path.join(root, 'docs', 'zh-CN', 'AGENTS.md'),
|
||||
@@ -742,6 +782,7 @@ module.exports = {
|
||||
formatExpectation,
|
||||
main,
|
||||
parseAgentsDocExpectations,
|
||||
parseCrossHarnessIdentityExpectations,
|
||||
parseCatalogDescriptionExpectations,
|
||||
parseReadmeExpectations,
|
||||
parseZhAgentsDocExpectations,
|
||||
@@ -751,6 +792,7 @@ module.exports = {
|
||||
syncCatalogDescription,
|
||||
syncEnglishAgents,
|
||||
syncEnglishReadme,
|
||||
syncCrossHarnessIdentity,
|
||||
syncZhAgents,
|
||||
syncZhDocsReadme,
|
||||
syncZhRootReadme,
|
||||
|
||||
@@ -95,6 +95,20 @@ commands/ - ${counts.commands} slash commands
|
||||
`);
|
||||
}
|
||||
|
||||
function writeCrossHarnessIdentityDocs(root, counts) {
|
||||
fs.writeFileSync(
|
||||
path.join(root, 'SOUL.md'),
|
||||
`Everything Claude Code (ECC) is a production-ready AI coding plugin with ${counts.agents} specialized agents, ${counts.skills} skills, ${counts.commands} commands, and automated hook workflows.\n`
|
||||
);
|
||||
|
||||
const geminiDir = path.join(root, '.gemini');
|
||||
fs.mkdirSync(geminiDir, { recursive: true });
|
||||
fs.writeFileSync(
|
||||
path.join(geminiDir, 'GEMINI.md'),
|
||||
`Everything Claude Code (ECC) is a cross-harness coding system with ${counts.agents} specialized agents, ${counts.skills} skills, and ${counts.commands} commands.\n`
|
||||
);
|
||||
}
|
||||
|
||||
function writeZhRootReadme(root, counts) {
|
||||
fs.writeFileSync(path.join(root, 'README.zh-CN.md'), `你现在可以使用 ${counts.agents} 个代理、${counts.skills} 个技能和 ${counts.commands} 个命令。\n`);
|
||||
}
|
||||
@@ -158,6 +172,7 @@ function writeCatalogFixture(root, options = {}) {
|
||||
|
||||
writeEnglishReadme(root, documentedCounts, { unrelatedSkillsCount });
|
||||
writeEnglishAgents(root, documentedCounts, { skillsMinimum });
|
||||
writeCrossHarnessIdentityDocs(root, documentedCounts);
|
||||
writeZhRootReadme(root, documentedCounts);
|
||||
writeZhDocsReadme(root, documentedCounts, { unrelatedSkillsCount });
|
||||
writeZhAgents(root, documentedCounts, { skillsMinimum });
|
||||
@@ -224,6 +239,8 @@ function runTests() {
|
||||
assert.ok(formatted.includes('README.md quick-start summary'));
|
||||
assert.ok(formatted.includes('README.md project tree'));
|
||||
assert.ok(formatted.includes('AGENTS.md summary'));
|
||||
assert.ok(formatted.includes('SOUL.md'));
|
||||
assert.ok(formatted.includes('.gemini/GEMINI.md'));
|
||||
assert.ok(formatted.includes('.claude-plugin/plugin.json description'));
|
||||
assert.ok(formatted.includes('.claude-plugin/marketplace.json plugin description'));
|
||||
assert.ok(formatted.includes('README.zh-CN.md quick-start summary'));
|
||||
@@ -250,6 +267,8 @@ function runTests() {
|
||||
|
||||
const readme = fs.readFileSync(path.join(testDir, 'README.md'), 'utf8');
|
||||
const agentsDoc = fs.readFileSync(path.join(testDir, 'AGENTS.md'), 'utf8');
|
||||
const soulDoc = fs.readFileSync(path.join(testDir, 'SOUL.md'), 'utf8');
|
||||
const geminiDoc = fs.readFileSync(path.join(testDir, '.gemini', 'GEMINI.md'), 'utf8');
|
||||
const zhReadme = fs.readFileSync(path.join(testDir, 'docs', 'zh-CN', 'README.md'), 'utf8');
|
||||
const zhAgentsDoc = fs.readFileSync(path.join(testDir, 'docs', 'zh-CN', 'AGENTS.md'), 'utf8');
|
||||
const pluginJson = fs.readFileSync(path.join(testDir, '.claude-plugin', 'plugin.json'), 'utf8');
|
||||
@@ -261,6 +280,8 @@ function runTests() {
|
||||
assert.ok(readme.includes('| Skills | 42 | .agents/skills/ |'));
|
||||
assert.ok(agentsDoc.includes('providing 1 specialized agents, 1+ skills, 1 commands'));
|
||||
assert.ok(agentsDoc.includes('skills/ - 1+ workflow skills and domain knowledge'));
|
||||
assert.ok(soulDoc.includes('with 1 specialized agents, 1 skills, 1 commands'));
|
||||
assert.ok(geminiDoc.includes('with 1 specialized agents, 1 skills, and 1 commands'));
|
||||
assert.ok(zhReadme.includes('| 技能 | 42 | .agents/skills/ |'));
|
||||
assert.ok(zhAgentsDoc.includes('提供 1 个专业代理、1+ 项技能、1 条命令'));
|
||||
assert.ok(zhAgentsDoc.includes('skills/ - 1+ 个工作流技能和领域知识'));
|
||||
|
||||
@@ -185,15 +185,18 @@ function runCatalogValidator(overrides = {}) {
|
||||
const argvPreamble = argv.map(arg => `process.argv.push(${JSON.stringify(arg)});`).join('\n');
|
||||
source = `${argvPreamble}\n${source}`;
|
||||
|
||||
const resolvedRoot = overrides.ROOT || repoRoot;
|
||||
const resolvedOverrides = {
|
||||
ROOT: repoRoot,
|
||||
README_PATH: path.join(repoRoot, 'README.md'),
|
||||
AGENTS_PATH: path.join(repoRoot, 'AGENTS.md'),
|
||||
README_ZH_CN_PATH: path.join(repoRoot, 'README.zh-CN.md'),
|
||||
DOCS_ZH_CN_README_PATH: path.join(repoRoot, 'docs', 'zh-CN', 'README.md'),
|
||||
DOCS_ZH_CN_AGENTS_PATH: path.join(repoRoot, 'docs', 'zh-CN', 'AGENTS.md'),
|
||||
PLUGIN_JSON_PATH: path.join(repoRoot, '.claude-plugin', 'plugin.json'),
|
||||
MARKETPLACE_JSON_PATH: path.join(repoRoot, '.claude-plugin', 'marketplace.json'),
|
||||
ROOT: resolvedRoot,
|
||||
README_PATH: path.join(resolvedRoot, 'README.md'),
|
||||
AGENTS_PATH: path.join(resolvedRoot, 'AGENTS.md'),
|
||||
README_ZH_CN_PATH: path.join(resolvedRoot, 'README.zh-CN.md'),
|
||||
DOCS_ZH_CN_README_PATH: path.join(resolvedRoot, 'docs', 'zh-CN', 'README.md'),
|
||||
DOCS_ZH_CN_AGENTS_PATH: path.join(resolvedRoot, 'docs', 'zh-CN', 'AGENTS.md'),
|
||||
PLUGIN_JSON_PATH: path.join(resolvedRoot, '.claude-plugin', 'plugin.json'),
|
||||
MARKETPLACE_JSON_PATH: path.join(resolvedRoot, '.claude-plugin', 'marketplace.json'),
|
||||
SOUL_PATH: path.join(resolvedRoot, 'SOUL.md'),
|
||||
GEMINI_PATH: path.join(resolvedRoot, '.gemini', 'GEMINI.md'),
|
||||
...overrides,
|
||||
};
|
||||
|
||||
@@ -279,6 +282,7 @@ function writeCatalogFixture(testDir, options = {}) {
|
||||
],
|
||||
pluginCounts = { agents: 1, skills: 1, commands: 1 },
|
||||
marketplaceCounts = { agents: 1, skills: 1, commands: 1 },
|
||||
crossHarnessCounts = { agents: 1, skills: 1, commands: 1 },
|
||||
} = options;
|
||||
|
||||
const readmePath = path.join(testDir, 'README.md');
|
||||
@@ -288,12 +292,15 @@ function writeCatalogFixture(testDir, options = {}) {
|
||||
const zhAgentsPath = path.join(testDir, 'docs', 'zh-CN', 'AGENTS.md');
|
||||
const pluginJsonPath = path.join(testDir, '.claude-plugin', 'plugin.json');
|
||||
const marketplaceJsonPath = path.join(testDir, '.claude-plugin', 'marketplace.json');
|
||||
const soulPath = path.join(testDir, 'SOUL.md');
|
||||
const geminiPath = path.join(testDir, '.gemini', 'GEMINI.md');
|
||||
|
||||
fs.mkdirSync(path.join(testDir, 'agents'), { recursive: true });
|
||||
fs.mkdirSync(path.join(testDir, 'commands'), { recursive: true });
|
||||
fs.mkdirSync(path.join(testDir, 'skills', 'demo-skill'), { recursive: true });
|
||||
fs.mkdirSync(path.join(testDir, 'docs', 'zh-CN'), { recursive: true });
|
||||
fs.mkdirSync(path.join(testDir, '.claude-plugin'), { recursive: true });
|
||||
fs.mkdirSync(path.join(testDir, '.gemini'), { recursive: true });
|
||||
|
||||
fs.writeFileSync(path.join(testDir, 'agents', 'planner.md'), '---\nmodel: sonnet\ntools: Read\n---\n# Planner');
|
||||
fs.writeFileSync(path.join(testDir, 'commands', 'plan.md'), '---\ndescription: Plan\n---\n# Plan');
|
||||
@@ -314,8 +321,16 @@ function writeCatalogFixture(testDir, options = {}) {
|
||||
description: `Marketplace plugin — ${marketplaceCounts.agents} agents, ${marketplaceCounts.skills} skills, ${marketplaceCounts.commands} legacy command shims`,
|
||||
}],
|
||||
}, null, 2));
|
||||
fs.writeFileSync(
|
||||
soulPath,
|
||||
`Everything Claude Code (ECC) is a production-ready AI coding plugin with ${crossHarnessCounts.agents} specialized agents, ${crossHarnessCounts.skills} skills, ${crossHarnessCounts.commands} commands, and automated hook workflows.\n`
|
||||
);
|
||||
fs.writeFileSync(
|
||||
geminiPath,
|
||||
`Everything Claude Code (ECC) is a cross-harness coding system with ${crossHarnessCounts.agents} specialized agents, ${crossHarnessCounts.skills} skills, and ${crossHarnessCounts.commands} commands.\n`
|
||||
);
|
||||
|
||||
return { readmePath, agentsPath, zhRootReadmePath, zhDocsReadmePath, zhAgentsPath, pluginJsonPath, marketplaceJsonPath };
|
||||
return { readmePath, agentsPath, zhRootReadmePath, zhDocsReadmePath, zhAgentsPath, pluginJsonPath, marketplaceJsonPath, soulPath, geminiPath };
|
||||
}
|
||||
|
||||
function runTests() {
|
||||
@@ -608,6 +623,42 @@ function runTests() {
|
||||
cleanupTestDir(testDir);
|
||||
})) passed++; else failed++;
|
||||
|
||||
if (test('fails when cross-harness identity counts drift', () => {
|
||||
const testDir = createTestDir();
|
||||
const {
|
||||
readmePath,
|
||||
agentsPath,
|
||||
soulPath,
|
||||
geminiPath,
|
||||
zhRootReadmePath,
|
||||
zhDocsReadmePath,
|
||||
zhAgentsPath,
|
||||
pluginJsonPath,
|
||||
marketplaceJsonPath,
|
||||
} = writeCatalogFixture(testDir, {
|
||||
crossHarnessCounts: { agents: 9, skills: 8, commands: 7 },
|
||||
});
|
||||
|
||||
const result = runCatalogValidator({
|
||||
ROOT: testDir,
|
||||
README_PATH: readmePath,
|
||||
AGENTS_PATH: agentsPath,
|
||||
SOUL_PATH: soulPath,
|
||||
GEMINI_PATH: geminiPath,
|
||||
README_ZH_CN_PATH: zhRootReadmePath,
|
||||
DOCS_ZH_CN_README_PATH: zhDocsReadmePath,
|
||||
DOCS_ZH_CN_AGENTS_PATH: zhAgentsPath,
|
||||
PLUGIN_JSON_PATH: pluginJsonPath,
|
||||
MARKETPLACE_JSON_PATH: marketplaceJsonPath,
|
||||
});
|
||||
|
||||
assert.strictEqual(result.code, 1, 'Should fail when cross-harness counts drift');
|
||||
const output = result.stdout + result.stderr;
|
||||
assert.ok(output.includes('SOUL.md'), 'Should report SOUL.md mismatches');
|
||||
assert.ok(output.includes('.gemini/GEMINI.md'), 'Should report GEMINI.md mismatches');
|
||||
cleanupTestDir(testDir);
|
||||
})) passed++; else failed++;
|
||||
|
||||
if (test('does not require obsolete cross-harness parity counts in README', () => {
|
||||
const testDir = createTestDir();
|
||||
const {
|
||||
@@ -677,6 +728,8 @@ function runTests() {
|
||||
const {
|
||||
readmePath,
|
||||
agentsPath,
|
||||
soulPath,
|
||||
geminiPath,
|
||||
zhRootReadmePath,
|
||||
zhDocsReadmePath,
|
||||
zhAgentsPath,
|
||||
@@ -694,6 +747,7 @@ function runTests() {
|
||||
zhAgentsSummaryCounts: { agents: 14, skills: 14, commands: 14 },
|
||||
pluginCounts: { agents: 18, skills: 18, commands: 18 },
|
||||
marketplaceCounts: { agents: 19, skills: 19, commands: 19 },
|
||||
crossHarnessCounts: { agents: 18, skills: 18, commands: 18 },
|
||||
zhAgentsStructureLines: [
|
||||
'agents/ — 15 个专业子代理',
|
||||
'skills/ — 16 个工作流技能和领域知识',
|
||||
@@ -711,6 +765,8 @@ function runTests() {
|
||||
DOCS_ZH_CN_AGENTS_PATH: zhAgentsPath,
|
||||
PLUGIN_JSON_PATH: pluginJsonPath,
|
||||
MARKETPLACE_JSON_PATH: marketplaceJsonPath,
|
||||
SOUL_PATH: soulPath,
|
||||
GEMINI_PATH: geminiPath,
|
||||
});
|
||||
|
||||
assert.strictEqual(result.code, 0, `Should sync and pass, got stderr: ${result.stderr}`);
|
||||
@@ -740,6 +796,10 @@ function runTests() {
|
||||
assert.ok(zhAgentsDoc.includes('commands/ — 1 个斜杠命令'), 'Should sync docs/zh-CN/AGENTS structure');
|
||||
assert.ok(pluginJson.includes('1 agents, 1 skills, 1 legacy command shims'), 'Should sync plugin manifest catalog description');
|
||||
assert.ok(marketplaceJson.includes('1 agents, 1 skills, 1 legacy command shims'), 'Should sync marketplace plugin catalog description');
|
||||
const soul = fs.readFileSync(soulPath, 'utf8');
|
||||
const gemini = fs.readFileSync(geminiPath, 'utf8');
|
||||
assert.ok(soul.includes('with 1 specialized agents, 1 skills, 1 commands'), 'Should sync SOUL.md catalog summary');
|
||||
assert.ok(gemini.includes('with 1 specialized agents, 1 skills, and 1 commands'), 'Should sync .gemini/GEMINI.md catalog summary');
|
||||
|
||||
cleanupTestDir(testDir);
|
||||
})) passed++; else failed++;
|
||||
|
||||
Reference in New Issue
Block a user