diff --git a/.aiox-core/development/tasks/validate-agents.md b/.aiox-core/development/tasks/validate-agents.md index 672d94a10f..f5fc4f8598 100644 --- a/.aiox-core/development/tasks/validate-agents.md +++ b/.aiox-core/development/tasks/validate-agents.md @@ -28,6 +28,18 @@ Story ACT-6: Framework integrity checking via `*validate-agents` command. Scan `.aiox-core/development/agents/` for all `.md` files. Expected agents: dev, qa, architect, pm, po, sm, analyst, data-engineer, ux-design-expert, devops, aiox-master, squad-creator +Also scan `squads//agents/` for every squad that ships agents. Squad scope +differs in two ways: + +- **Command uniqueness is per scope.** Core agents share one namespace and each squad + has its own — the same command name in two different squads is not a collision. +- **Dependencies resolve inside the squad** (`squads///`), not in the core + development directories. `reference_files` are repo-relative instead. + +Use `--core-only` to restrict the run to the 12 core agents. + +Files starting with `_` are skipped by design (partials, drafts). + ### Step 2: Parse YAML Block For each agent file: @@ -77,8 +89,11 @@ For each command in `commands` array: ### Step 7: Cross-Agent Validation 1. Verify no duplicate agent IDs across files -2. Verify all 12 expected agents are present +2. Verify all 12 expected core agents are present (squad agents are additional) 3. Verify `*yolo` command exists (universal command) +4. Verify every agent's YAML block PARSES. An unparseable block is an ERROR, not a + silent skip: before this check existed, one broken file aborted the whole scan and + the run still reported success. ### Step 8: Generate Report @@ -110,8 +125,8 @@ Summary: 11 passed, 1 warning, 0 failed - `js-yaml` - YAML parsing - `fs` - File system access -- Agent files in `.aiox-core/development/agents/` -- Task files in `.aiox-core/development/tasks/` +- Agent files in `.aiox-core/development/agents/` and `squads//agents/` +- Task files in `.aiox-core/development/tasks/` and `squads//tasks/` - `unified-activation-pipeline.js` - Pipeline reference check --- diff --git a/.aiox-core/infrastructure/scripts/validate-agents.js b/.aiox-core/infrastructure/scripts/validate-agents.js index 29c0e940fe..187a4ec27a 100644 --- a/.aiox-core/infrastructure/scripts/validate-agents.js +++ b/.aiox-core/infrastructure/scripts/validate-agents.js @@ -6,13 +6,21 @@ * Validates all agent definitions for consistency according to the * Agent Consistency Refactor PRD requirements: * - * 1. Command uniqueness across agents (1 command = 1 owner) - * 2. Dependency existence verification - * 3. Format schema validation - * 4. Cross-agent reference validation + * 1. YAML parseability (a broken block is reported, not swallowed) + * 2. Command uniqueness within each scope (1 command = 1 owner) + * 3. Dependency existence verification + * 4. Format schema validation + * 5. Cross-agent reference validation + * + * Scope: core agents in .aiox-core/development/agents/ AND squad agents in + * squads//agents/. Command uniqueness is checked per scope — core agents + * share one namespace and each squad has its own, so the same command name in + * two different squads is not a conflict. Squad dependencies resolve against + * squads/// rather than the core development directories. * * Usage: - * node validate-agents.js Validate all agents + * node validate-agents.js Validate core + squad agents + * node validate-agents.js --core-only Validate only core agents * node validate-agents.js --json Output as JSON * node validate-agents.js --fix-suggestions Show fix suggestions * @@ -26,7 +34,9 @@ const path = require('path'); const yaml = require('js-yaml'); // Paths -const ROOT_DIR = path.join(__dirname, '..', '..'); +const ROOT_DIR = path.join(__dirname, '..', '..'); // .aiox-core +const REPO_ROOT = path.join(ROOT_DIR, '..'); // repository root +const SQUADS_DIR = path.join(REPO_ROOT, 'squads'); const AGENTS_DIR = path.join(ROOT_DIR, 'development', 'agents'); const TASKS_DIR = path.join(ROOT_DIR, 'development', 'tasks'); const TEMPLATES_DIR = path.join(ROOT_DIR, 'development', 'templates'); @@ -36,6 +46,26 @@ const UTILS_DIR = path.join(ROOT_DIR, 'development', 'utils'); const WORKFLOWS_DIR = path.join(ROOT_DIR, 'development', 'workflows'); const SCRIPTS_DIR = path.join(ROOT_DIR, 'development', 'scripts'); +const CORE_SCOPE = 'core'; + +// Where each file-based dependency type lives, for core agents. +const CORE_DEP_DIRS = { + tasks: TASKS_DIR, + templates: TEMPLATES_DIR, + checklists: CHECKLISTS_DIR, + data: DATA_DIR, + utils: UTILS_DIR, + workflows: WORKFLOWS_DIR, + scripts: SCRIPTS_DIR, +}; + +// Same types, resolved inside a squad directory (squads///). +function squadDepDirs(squadRoot) { + return Object.fromEntries( + Object.keys(CORE_DEP_DIRS).map((type) => [type, path.join(squadRoot, type)]) + ); +} + // Commands that are allowed to be shared by multiple agents // These are utility/infrastructure commands, not domain-specific const SHARED_COMMANDS = new Set([ @@ -81,36 +111,109 @@ function extractYamlFromMarkdown(content) { } /** - * Load all agent files + * Load agent files from a single directory. + * + * A file whose YAML does not parse is recorded in parseErrors instead of + * aborting the scan — previously one broken block stopped every remaining + * agent from being loaded at all, and the failure surfaced only as a console + * message while the run still reported success. */ -async function loadAllAgents() { +async function loadAgentsFromDir(dir, scope, depDirs) { const agents = []; + const parseErrors = []; + let files; try { - const files = await fs.readdir(AGENTS_DIR); - for (const file of files) { - if (file.endsWith('.md') && !file.startsWith('_')) { - const filePath = path.join(AGENTS_DIR, file); - const content = await fs.readFile(filePath, 'utf-8'); - const parsed = extractYamlFromMarkdown(content); - - if (parsed?.agent) { - agents.push({ - file, - path: filePath, - id: parsed.agent.id || file.replace('.md', ''), - name: parsed.agent.name, - commands: parsed.commands || [], - dependencies: parsed.dependencies || {}, - parsed, - }); - } + files = await fs.readdir(dir); + } catch { + return { agents, parseErrors }; // directory absent — nothing to validate + } + + for (const file of files) { + if (!file.endsWith('.md') || file.startsWith('_')) continue; + + const filePath = path.join(dir, file); + try { + const content = await fs.readFile(filePath, 'utf-8'); + const parsed = extractYamlFromMarkdown(content); + + if (parsed?.agent) { + agents.push({ + file, + path: filePath, + scope, + depDirs, + id: parsed.agent.id || file.replace('.md', ''), + name: parsed.agent.name, + commands: parsed.commands || [], + dependencies: parsed.dependencies || {}, + parsed, + }); } + } catch (error) { + parseErrors.push({ + type: 'INVALID_YAML', + scope, + agent: file.replace('.md', ''), + file, + path: filePath, + message: `Unparseable YAML in ${scope}/${file}: ${String(error.message).split('\n')[0]}`, + suggestion: + 'Fix the embedded YAML block. A common cause is a sequence entry like `- "term" (note)`, where the text after the closing quote is a stray token — wrap the whole entry in single quotes.', + }); } - } catch (error) { - console.error(`Error reading agents directory: ${error.message}`); } + return { agents, parseErrors }; +} + +/** + * Discover squads that ship agents (squads//agents/). + */ +async function discoverSquads() { + try { + const entries = await fs.readdir(SQUADS_DIR, { withFileTypes: true }); + return entries + .filter((e) => e.isDirectory()) + .map((e) => ({ + name: e.name, + root: path.join(SQUADS_DIR, e.name), + agentsDir: path.join(SQUADS_DIR, e.name, 'agents'), + })); + } catch { + return []; // no squads/ directory (e.g. project-mode install) + } +} + +/** + * Load core agents plus, unless disabled, every squad's agents. + * Returns { agents, parseErrors, scopes }. + */ +async function loadAgents({ includeSquads = true } = {}) { + const core = await loadAgentsFromDir(AGENTS_DIR, CORE_SCOPE, CORE_DEP_DIRS); + const agents = [...core.agents]; + const parseErrors = [...core.parseErrors]; + const scopes = [{ scope: CORE_SCOPE, count: core.agents.length }]; + + if (includeSquads) { + for (const squad of await discoverSquads()) { + const scope = `squad:${squad.name}`; + const loaded = await loadAgentsFromDir(squad.agentsDir, scope, squadDepDirs(squad.root)); + if (loaded.agents.length === 0 && loaded.parseErrors.length === 0) continue; + agents.push(...loaded.agents); + parseErrors.push(...loaded.parseErrors); + scopes.push({ scope, count: loaded.agents.length }); + } + } + + return { agents, parseErrors, scopes }; +} + +/** + * Backwards-compatible wrapper: returns just the agent list. + */ +async function loadAllAgents(options = {}) { + const { agents } = await loadAgents(options); return agents; } @@ -127,35 +230,50 @@ async function fileExists(filePath) { } /** - * Validate command uniqueness across agents - * Returns: { errors: [], warnings: [], commandOwners: Map } + * Extract a command name from any of the three accepted command shapes. + */ +function commandName(cmd) { + if (typeof cmd === 'string') { + // String format: 'command: description' + return cmd.split(':')[0].trim(); + } + if (cmd && cmd.name) { + // Explicit format: { name: 'command', ... } + return cmd.name; + } + if (typeof cmd === 'object' && cmd !== null) { + // Shorthand format: { command: 'description' } - take first key + return Object.keys(cmd)[0]?.split(' ')[0]; // Handle 'command {args}' format + } + return undefined; +} + +/** + * Validate command uniqueness within each scope. + * + * Scopes are separate namespaces: core agents are checked against each other, + * and each squad against itself. A command named the same in two different + * squads is not a collision, so cross-scope pairs are never reported. + * + * Returns: { errors: [], warnings: [], commandOwners: Map> } */ function validateCommandUniqueness(agents) { - const commandOwners = new Map(); // command -> [{ agent, hasVisibility }] + const commandOwners = new Map(); // scope -> Map(command -> [{ agent, file, hasVisibility }]) const errors = []; const warnings = []; for (const agent of agents) { if (!Array.isArray(agent.commands)) continue; + const scope = agent.scope || CORE_SCOPE; + if (!commandOwners.has(scope)) commandOwners.set(scope, new Map()); + const scopeOwners = commandOwners.get(scope); + for (const cmd of agent.commands) { - let cmdName; - if (typeof cmd === 'string') { - // String format: 'command: description' - cmdName = cmd.split(':')[0].trim(); - } else if (cmd.name) { - // Explicit format: { name: 'command', ... } - cmdName = cmd.name; - } else if (typeof cmd === 'object') { - // Shorthand format: { command: 'description' } - take first key - const keys = Object.keys(cmd); - cmdName = keys[0]?.split(' ')[0]; // Handle 'command {args}' format - } + const cmdName = commandName(cmd); if (!cmdName) continue; - if (!commandOwners.has(cmdName)) { - commandOwners.set(cmdName, []); - } - commandOwners.get(cmdName).push({ + if (!scopeOwners.has(cmdName)) scopeOwners.set(cmdName, []); + scopeOwners.get(cmdName).push({ agent: agent.id, file: agent.file, hasVisibility: cmd.visibility !== undefined, @@ -163,17 +281,20 @@ function validateCommandUniqueness(agents) { } } - // Check for duplicates - for (const [cmd, owners] of commandOwners) { - if (owners.length > 1 && !SHARED_COMMANDS.has(cmd)) { - const ownerList = owners.map((o) => `@${o.agent}`).join(', '); - errors.push({ - type: 'DUPLICATE_COMMAND', - command: cmd, - owners: owners.map((o) => o.agent), - message: `Command "*${cmd}" has multiple owners: ${ownerList}`, - suggestion: `Keep "*${cmd}" only in the primary owner agent and remove from others, or add to SHARED_COMMANDS if intentionally shared.`, - }); + // Check for duplicates, one scope at a time + for (const [scope, scopeOwners] of commandOwners) { + for (const [cmd, owners] of scopeOwners) { + if (owners.length > 1 && !SHARED_COMMANDS.has(cmd)) { + const ownerList = owners.map((o) => `@${o.agent}`).join(', '); + errors.push({ + type: 'DUPLICATE_COMMAND', + scope, + command: cmd, + owners: owners.map((o) => o.agent), + message: `[${scope}] Command "*${cmd}" has multiple owners: ${ownerList}`, + suggestion: `Keep "*${cmd}" only in the primary owner agent and remove from others, or add to SHARED_COMMANDS if intentionally shared.`, + }); + } } } @@ -187,31 +308,45 @@ async function validateDependencies(agents) { const errors = []; const warnings = []; - const depDirs = { - tasks: TASKS_DIR, - templates: TEMPLATES_DIR, - checklists: CHECKLISTS_DIR, - data: DATA_DIR, - utils: UTILS_DIR, - workflows: WORKFLOWS_DIR, - scripts: SCRIPTS_DIR, - }; - // Dependency types that are not file-based (external tools, integrations) const skipDepTypes = new Set(['tools', 'coderabbit_integration', 'pr_automation', 'repository_agnostic_design', 'git_authority', 'workflow_examples']); for (const agent of agents) { const deps = agent.dependencies; + // Squad agents resolve dependencies inside their own squad directory. + const depDirs = agent.depDirs || CORE_DEP_DIRS; for (const [depType, depList] of Object.entries(deps)) { // Skip non-file-based dependency types if (skipDepTypes.has(depType)) continue; if (!Array.isArray(depList)) continue; + // reference_files hold repo-relative paths, not / entries. + if (depType === 'reference_files') { + for (const refFile of depList) { + if (typeof refFile !== 'string') continue; + const refPath = path.join(REPO_ROOT, refFile); + if (!(await fileExists(refPath))) { + warnings.push({ + type: 'MISSING_REFERENCE_FILE', + scope: agent.scope, + agent: agent.id, + depType, + depFile: refFile, + expectedPath: refPath, + message: `Missing reference file: @${agent.id} → ${refFile}`, + suggestion: `Create ${refFile} or remove it from the agent's reference_files.`, + }); + } + } + continue; + } + const depDir = depDirs[depType]; if (!depDir) { warnings.push({ type: 'UNKNOWN_DEP_TYPE', + scope: agent.scope, agent: agent.id, depType, message: `Unknown dependency type "${depType}" in @${agent.id}`, @@ -227,6 +362,7 @@ async function validateDependencies(agents) { // Missing dependencies are warnings, not errors (pre-existing technical debt) warnings.push({ type: 'MISSING_DEPENDENCY', + scope: agent.scope, agent: agent.id, depType, depFile, @@ -342,7 +478,7 @@ function validateAgentFormat(agents) { */ function formatResults(results, showSuggestions = false) { const lines = []; - const { commandValidation, dependencyValidation, formatValidation, summary } = results; + const { parseValidation, commandValidation, dependencyValidation, formatValidation, summary } = results; lines.push(''); lines.push('━'.repeat(60)); @@ -350,6 +486,21 @@ function formatResults(results, showSuggestions = false) { lines.push('━'.repeat(60)); lines.push(''); + // YAML parseability — must come first: an unparseable agent cannot be checked at all + lines.push('🔍 YAML Parse Check'); + lines.push('─'.repeat(40)); + if (parseValidation.errors.length === 0) { + lines.push(' ✅ All agent definitions parse as YAML'); + } else { + for (const err of parseValidation.errors) { + lines.push(` ❌ ${err.message}`); + if (showSuggestions && err.suggestion) { + lines.push(` 💡 ${err.suggestion}`); + } + } + } + lines.push(''); + // Command Uniqueness lines.push('📋 Command Uniqueness Check'); lines.push('─'.repeat(40)); @@ -413,6 +564,9 @@ function formatResults(results, showSuggestions = false) { lines.push(' Summary'); lines.push('━'.repeat(60)); lines.push(` Agents validated: ${summary.totalAgents}`); + for (const { scope, count } of summary.scopes || []) { + lines.push(` • ${scope}: ${count}`); + } lines.push(` Errors: ${summary.totalErrors}`); lines.push(` Warnings: ${summary.totalWarnings}`); lines.push(''); @@ -431,38 +585,43 @@ function formatResults(results, showSuggestions = false) { * Main validation function */ async function validateAgents(options = {}) { - const { json = false, fixSuggestions = false } = options; + const { json = false, fixSuggestions = false, coreOnly = false } = options; - // Load all agents - const agents = await loadAllAgents(); + // Load core agents and, unless restricted, every squad's agents + const { agents, parseErrors, scopes } = await loadAgents({ includeSquads: !coreOnly }); - if (agents.length === 0) { + if (agents.length === 0 && parseErrors.length === 0) { console.error('No agents found in', AGENTS_DIR); process.exit(1); } // Run validations + const parseValidation = { errors: parseErrors, warnings: [] }; const commandValidation = validateCommandUniqueness(agents); const dependencyValidation = await validateDependencies(agents); const formatValidation = validateAgentFormat(agents); - // Calculate summary + // Calculate summary — an unparseable definition is an error, not a silent skip const totalErrors = + parseValidation.errors.length + commandValidation.errors.length + dependencyValidation.errors.length + formatValidation.errors.length; const totalWarnings = + parseValidation.warnings.length + commandValidation.warnings.length + dependencyValidation.warnings.length + formatValidation.warnings.length; const results = { + parseValidation, commandValidation, dependencyValidation, formatValidation, summary: { totalAgents: agents.length, + scopes, totalErrors, totalWarnings, valid: totalErrors === 0, @@ -502,6 +661,7 @@ Exit codes: const options = { json: args.includes('--json'), fixSuggestions: args.includes('--fix-suggestions') || args.includes('--fix'), + coreOnly: args.includes('--core-only'), }; const results = await validateAgents(options); @@ -514,7 +674,14 @@ module.exports = { validateCommandUniqueness, validateDependencies, validateAgentFormat, + // loadAllAgents mantém a assinatura antiga (devolve só a lista) para não quebrar + // quem já consome; loadAgents é o novo, com parseErrors e escopos. loadAllAgents, + loadAgents, + loadAgentsFromDir, + discoverSquads, + commandName, + CORE_SCOPE, }; // Run CLI if called directly diff --git a/.aiox-core/install-manifest.yaml b/.aiox-core/install-manifest.yaml index 0bd15989eb..c9fbfe350f 100644 --- a/.aiox-core/install-manifest.yaml +++ b/.aiox-core/install-manifest.yaml @@ -8,7 +8,7 @@ # - File types for categorization # version: 5.2.9 -generated_at: "2026-05-21T13:48:41.292Z" +generated_at: "2026-07-27T13:49:10.653Z" generator: scripts/generate-install-manifest.js file_count: 1129 files: @@ -2661,9 +2661,9 @@ files: type: task size: 13275 - path: development/tasks/validate-agents.md - hash: sha256:b278ba27cf8171d143aba30bd2f708b9226526dae70e9b881f52b5e1e908525f + hash: sha256:66200c9ce5fce7086f7982af8cff13b12bfbd506714a01d334c58f8d45d04107 type: task - size: 3595 + size: 4455 - path: development/tasks/validate-next-story.md hash: sha256:277faba94cba30ac3773159d641fc2b8a345efd70dcfef6bae15f8a6280128ea type: task @@ -2719,19 +2719,19 @@ files: - path: development/templates/service-template/__tests__/index.test.ts.hbs hash: sha256:4617c189e75ab362d4ef2cabcc3ccce3480f914fd915af550469c17d1b68a4fe type: template - size: 9573 + size: 9810 - path: development/templates/service-template/client.ts.hbs hash: sha256:f342c60695fe611192002bdb8c04b3a0dbce6345b7fa39834ea1898f71689198 type: template - size: 11810 + size: 12213 - path: development/templates/service-template/errors.ts.hbs hash: sha256:e0be40d8be19b71b26e35778eadffb20198e7ca88e9d140db9da1bfe12de01ec type: template - size: 5213 + size: 5395 - path: development/templates/service-template/index.ts.hbs hash: sha256:d44012d54b76ab98356c7163d257ca939f7fed122f10fecf896fe1e7e206d10a type: template - size: 3086 + size: 3206 - path: development/templates/service-template/jest.config.js hash: sha256:1681bfd7fbc0d330d3487d3427515847c4d57ef300833f573af59e0ad69ed159 type: template @@ -2739,11 +2739,11 @@ files: - path: development/templates/service-template/package.json.hbs hash: sha256:d89d35f56992ee95c2ceddf17fa1d455c18007a4d24af914ba83cf4abc38bca9 type: template - size: 2227 + size: 2314 - path: development/templates/service-template/README.md.hbs hash: sha256:2c3dd4c2bf6df56b9b6db439977be7e1cc35820438c0e023140eccf6ccd227a0 type: template - size: 3426 + size: 3584 - path: development/templates/service-template/tsconfig.json hash: sha256:8b465fcbdd45c4d6821ba99aea62f2bd7998b1bca8de80486a1525e77d43c9a1 type: template @@ -2751,7 +2751,7 @@ files: - path: development/templates/service-template/types.ts.hbs hash: sha256:3e52e0195003be8cd1225a3f27f4d040686c8b8c7762f71b41055f04cd1b841b type: template - size: 2516 + size: 2661 - path: development/templates/squad-template/agents/example-agent.yaml hash: sha256:824a1b349965e5d4ae85458c231b78260dc65497da75dada25b271f2cabbbe67 type: agent @@ -2759,7 +2759,7 @@ files: - path: development/templates/squad-template/LICENSE hash: sha256:ff7017aa403270cf2c440f5ccb4240d0b08e54d8bf8a0424d34166e8f3e10138 type: template - size: 1071 + size: 1092 - path: development/templates/squad-template/package.json hash: sha256:8f68627a0d74e49f94ae382d0c2b56ecb5889d00f3095966c742fb5afaf363db type: template @@ -3477,9 +3477,9 @@ files: type: script size: 18245 - path: infrastructure/scripts/validate-agents.js - hash: sha256:5f5f89a1fcf02ba340772ed30ade56fc346114d7a4d43e6d69af40858c64b180 + hash: sha256:708c52b9c80dae897878a345dc5079cc6b6567050a301fd2b2020672dd8314ea type: script - size: 14900 + size: 21246 - path: infrastructure/scripts/validate-claude-integration.js hash: sha256:e9d6776b9af9e9233e50aa7664eef7c67937af0ebabca1a3aa26c518debf8178 type: script @@ -3523,11 +3523,11 @@ files: - path: infrastructure/templates/aiox-sync.yaml.template hash: sha256:0040ad8a9e25716a28631b102c9448b72fd72e84f992c3926eb97e9e514744bb type: template - size: 8385 + size: 8567 - path: infrastructure/templates/coderabbit.yaml.template hash: sha256:91a4a76bbc40767a4072fb6a87c480902bb800cfb0a11e9fc1b3183d8f7f3a80 type: template - size: 8042 + size: 8321 - path: infrastructure/templates/core-config/core-config-brownfield.tmpl.yaml hash: sha256:9bdb0c0e09c765c991f9f142921f7f8e2c0d0ada717f41254161465dc0622d02 type: template @@ -3539,11 +3539,11 @@ files: - path: infrastructure/templates/github-workflows/ci.yml.template hash: sha256:acbfa2a8a84141fd6a6b205eac74719772f01c221c0afe22ce951356f06a605d type: template - size: 4920 + size: 5089 - path: infrastructure/templates/github-workflows/pr-automation.yml.template hash: sha256:c236077b4567965a917e48df9a91cc42153ff97b00a9021c41a7e28179be9d0f type: template - size: 10609 + size: 10939 - path: infrastructure/templates/github-workflows/README.md hash: sha256:6b7b5cb32c28b3e562c81a96e2573ea61849b138c93ccac6e93c3adac26cadb5 type: template @@ -3551,23 +3551,23 @@ files: - path: infrastructure/templates/github-workflows/release.yml.template hash: sha256:b771145e61a254a88dc6cca07869e4ece8229ce18be87132f59489cdf9a66ec6 type: template - size: 6595 + size: 6791 - path: infrastructure/templates/gitignore/gitignore-aiox-base.tmpl hash: sha256:9088975ee2bf4d88e23db6ac3ea5d27cccdc72b03db44450300e2f872b02e935 type: template - size: 788 + size: 851 - path: infrastructure/templates/gitignore/gitignore-brownfield-merge.tmpl hash: sha256:ce4291a3cf5677050c9dafa320809e6b0ca5db7e7f7da0382d2396e32016a989 type: template - size: 488 + size: 506 - path: infrastructure/templates/gitignore/gitignore-node.tmpl hash: sha256:5179f78de7483274f5d7182569229088c71934db1fd37a63a40b3c6b815c9c8e type: template - size: 951 + size: 1036 - path: infrastructure/templates/gitignore/gitignore-python.tmpl hash: sha256:d7aac0b1e6e340b774a372a9102b4379722588449ca82ac468cf77804bbc1e55 type: template - size: 1580 + size: 1725 - path: infrastructure/templates/project-docs/coding-standards-tmpl.md hash: sha256:377acf85463df8ac9923fc59d7cfeba68a82f8353b99948ea1d28688e88bc4a9 type: template @@ -3663,43 +3663,43 @@ files: - path: monitor/hooks/lib/__init__.py hash: sha256:bfab6ee249c52f412c02502479da649b69d044938acaa6ab0aa39dafe6dee9bf type: monitor - size: 29 + size: 30 - path: monitor/hooks/lib/enrich.py hash: sha256:20dfa73b4b20d7a767e52c3ec90919709c4447c6e230902ba797833fc6ddc22c type: monitor - size: 1644 + size: 1702 - path: monitor/hooks/lib/send_event.py hash: sha256:59d61311f718fb373a5cf85fd7a01c23a4fd727e8e022ad6930bba533ef4615d type: monitor - size: 1190 + size: 1237 - path: monitor/hooks/notification.py hash: sha256:8a1a6ce0ff2b542014de177006093b9caec9b594e938a343dc6bd62df2504f22 type: monitor - size: 499 + size: 528 - path: monitor/hooks/post_tool_use.py hash: sha256:47dbe37073d432c55657647fc5b907ddb56efa859d5c3205e8362aa916d55434 type: monitor - size: 1140 + size: 1185 - path: monitor/hooks/pre_compact.py hash: sha256:f287cf45e83deed6f1bc0e30bd9348dfa1bf08ad770c5e58bb34e3feb210b30b type: monitor - size: 500 + size: 529 - path: monitor/hooks/pre_tool_use.py hash: sha256:a4d1d3ffdae9349e26a383c67c9137effff7d164ac45b2c87eea9fa1ab0d6d98 type: monitor - size: 981 + size: 1021 - path: monitor/hooks/stop.py hash: sha256:edb382f0cf46281a11a8588bc20eafa7aa2b5cc3f4ad775d71b3d20a7cfab385 type: monitor - size: 490 + size: 519 - path: monitor/hooks/subagent_stop.py hash: sha256:fa5357309247c71551dba0a19f28dd09bebde749db033d6657203b50929c0a42 type: monitor - size: 512 + size: 541 - path: monitor/hooks/user_prompt_submit.py hash: sha256:af57dca79ef55cdf274432f4abb4c20a9778b95e107ca148f47ace14782c5828 type: monitor - size: 818 + size: 856 - path: package.json hash: sha256:d8dbe037240a366d545ca4259d2059e705b709706dcf2a18a5a52d9b543b7ed9 type: other @@ -3847,7 +3847,7 @@ files: - path: product/templates/adr.hbs hash: sha256:d68653cae9e64414ad4f58ea941b6c6e337c5324c2c7247043eca1461a652d10 type: template - size: 2212 + size: 2337 - path: product/templates/agent-template.yaml hash: sha256:98676fcc493c0d5f09264dcc52fcc2cf1129f9a195824ecb4c2ec035c2515121 type: template @@ -3899,7 +3899,7 @@ files: - path: product/templates/dbdr.hbs hash: sha256:5a2781ffaa3da9fc663667b5a63a70b7edfc478ed14cad02fc6ed237ff216315 type: template - size: 4139 + size: 4380 - path: product/templates/design-story-tmpl.yaml hash: sha256:2bfefc11ae2bcfc679dbd924c58f8b764fa23538c14cb25344d6edef41968f29 type: template @@ -3963,7 +3963,7 @@ files: - path: product/templates/epic.hbs hash: sha256:dcbcc26f6dd8f3782b3ef17aee049b689f1d6d92931615c3df9513eca0de2ef7 type: template - size: 3868 + size: 4080 - path: product/templates/eslintrc-security.json hash: sha256:657d40117261d6a52083984d29f9f88e79040926a64aa4c2058a602bfe91e0d5 type: template @@ -4071,7 +4071,7 @@ files: - path: product/templates/pmdr.hbs hash: sha256:d529cebbb562faa82c70477ece70de7cda871eaa6896f2962b48b2a8b67b1cbe type: template - size: 3239 + size: 3425 - path: product/templates/prd-tmpl.yaml hash: sha256:25c239f40e05f24aee1986601a98865188dbe3ea00a705028efc3adad6d420f3 type: template @@ -4079,11 +4079,11 @@ files: - path: product/templates/prd-v2.0.hbs hash: sha256:21a20ef5333a85a11f5326d35714e7939b51bab22bd6e28d49bacab755763bea type: template - size: 4512 + size: 4728 - path: product/templates/prd.hbs hash: sha256:4a1a030a5388c6a8bf2ce6ea85e54cae6cf1fe64f1bb2af7f17d349d3c24bf1d type: template - size: 3425 + size: 3626 - path: product/templates/project-brief-tmpl.yaml hash: sha256:b8d388268c24dc5018f48a87036d591b11cb122fafe9b59c17809b06ea5d9d58 type: template @@ -4131,7 +4131,7 @@ files: - path: product/templates/story.hbs hash: sha256:3f0ac8b39907634a2b53f43079afc33663eee76f46e680d318ff253e0befc2c4 type: template - size: 5583 + size: 5846 - path: product/templates/task-execution-report.md hash: sha256:e0f08a3e199234f3d2207ba8f435786b7d8e1b36174f46cb82fc3666b9a9309e type: template @@ -4143,67 +4143,67 @@ files: - path: product/templates/task.hbs hash: sha256:621e987e142c455cd290dc85d990ab860faa0221f66cf1f57ac296b076889ea5 type: template - size: 2705 + size: 2875 - path: product/templates/tmpl-comment-on-examples.sql hash: sha256:254002c3fbc63cfcc5848b1d4b15822ce240bf5f57e6a1c8bb984e797edc2691 type: template - size: 6215 + size: 6373 - path: product/templates/tmpl-migration-script.sql hash: sha256:44ef63ea475526d21a11e3c667c9fdb78a9fddace80fdbaa2312b7f2724fbbb5 type: template - size: 2947 + size: 3038 - path: product/templates/tmpl-rls-granular-policies.sql hash: sha256:36c2fd8c6d9eebb5d164acb0fb0c87bc384d389264b4429ce21e77e06318f5f3 type: template - size: 3322 + size: 3426 - path: product/templates/tmpl-rls-kiss-policy.sql hash: sha256:5210d37fce62e5a9a00e8d5366f5f75653cd518be73fbf96333ed8a6712453c7 type: template - size: 299 + size: 309 - path: product/templates/tmpl-rls-roles.sql hash: sha256:2d032a608a8e87440c3a430c7d69ddf9393d8813d8d4129270f640dd847425c3 type: template - size: 4592 + size: 4727 - path: product/templates/tmpl-rls-simple.sql hash: sha256:f67af0fa1cdd2f2af9eab31575ac3656d82457421208fd9ccb8b57ca9785275e type: template - size: 2915 + size: 2992 - path: product/templates/tmpl-rls-tenant.sql hash: sha256:36629ed87a2c72311809cc3fb96298b6f38716bba35bc56c550ac39d3321757a type: template - size: 4978 + size: 5130 - path: product/templates/tmpl-rollback-script.sql hash: sha256:8b84046a98f1163faf7350322f43831447617c5a63a94c88c1a71b49804e022b type: template - size: 2657 + size: 2734 - path: product/templates/tmpl-seed-data.sql hash: sha256:a65e73298f46cd6a8e700f29b9d8d26e769e12a57751a943a63fd0fe15768615 type: template - size: 5576 + size: 5716 - path: product/templates/tmpl-smoke-test.sql hash: sha256:aee7e48bb6d9c093769dee215cacc9769939501914e20e5ea8435b25fad10f3c type: template - size: 723 + size: 739 - path: product/templates/tmpl-staging-copy-merge.sql hash: sha256:55988caeb47cc04261665ba7a37f4caa2aa5fac2e776fdbc5964e0587af24450 type: template - size: 4081 + size: 4220 - path: product/templates/tmpl-stored-proc.sql hash: sha256:2b205ff99dc0adfade6047a4d79f5b50109e50ceb45386e5c886437692c7a2a3 type: template - size: 3839 + size: 3979 - path: product/templates/tmpl-trigger.sql hash: sha256:93abdc92e1b475d1370094e69a9d1b18afd804da6acb768b878355c798bd8e0e type: template - size: 5272 + size: 5424 - path: product/templates/tmpl-view-materialized.sql hash: sha256:47935510f03d4ad9b2200748e65441ce6c2d6a7c74750395eca6831d77c48e91 type: template - size: 4363 + size: 4496 - path: product/templates/tmpl-view.sql hash: sha256:22557b076003a856b32397f05fa44245a126521de907058a95e14dd02da67aff type: template - size: 4916 + size: 5093 - path: product/templates/token-exports-css-tmpl.css hash: sha256:d937b8d61cdc9e5b10fdff871c6cb41c9f756004d060d671e0ae26624a047f62 type: template diff --git a/squads/claude-code-mastery/agents/claude-mastery-chief.md b/squads/claude-code-mastery/agents/claude-mastery-chief.md index 66bfa8fbd7..64b35e7189 100644 --- a/squads/claude-code-mastery/agents/claude-mastery-chief.md +++ b/squads/claude-code-mastery/agents/claude-mastery-chief.md @@ -20,8 +20,9 @@ activation-instructions: Display greeting using native context (zero JS execution): 0. GREENFIELD GUARD: If gitStatus in system prompt says "Is a git repository: false" OR git commands return "not a git repository": - For substep 2: skip the "Branch:" append - - For substep 3: show "Project Status: Greenfield project — no git repository detected" instead of git narrative - - Do NOT run any git commands during activation + - For substep 3: show "📊 **Project Status:** No git repository detected in the working directory" instead of git narrative + - After substep 6, if the working directory is a user home directory (e.g. `C:\Users\{name}`, `/home/{name}`, `/Users/{name}`) or any other non-project directory — decided from the path already in the system prompt, zero I/O: show "💡 **Tip:** Activate agents from inside the project directory — never run `git init` in a home directory." + - Do NOT run any git commands during activation — they will fail and produce errors 1. Show: "{icon} {persona_profile.communication.greeting_levels.archetypal}" + permission badge from current permission mode 2. Show: "**Role:** {persona.role}" - Append: "Story: {active story from docs/stories/}" if detected + "Branch: `{branch}`" if not main/master diff --git a/squads/claude-code-mastery/agents/config-engineer.md b/squads/claude-code-mastery/agents/config-engineer.md index 86e52b9e5d..a36839ed0a 100644 --- a/squads/claude-code-mastery/agents/config-engineer.md +++ b/squads/claude-code-mastery/agents/config-engineer.md @@ -21,9 +21,11 @@ activation-instructions: Display greeting using native context (zero JS execution): 0. GREENFIELD GUARD: If gitStatus in system prompt says "Is a git repository: false" OR git commands return "not a git repository": - For substep 2: skip the "Branch:" append - - For substep 3: show "**Project Status:** Greenfield project -- no git repository detected" instead of git narrative - - After substep 6: show "**Recommended:** Run `*configure` to bootstrap Claude Code settings for this project" - - Do NOT run any git commands during activation -- they will fail and produce errors + - For substep 3: show "📊 **Project Status:** No git repository detected in the working directory" instead of git narrative + - After substep 6, decide from the working directory path already in the system prompt (zero I/O): + - If it is a user home directory (e.g. `C:\Users\{name}`, `/home/{name}`, `/Users/{name}`) or any other non-project directory: show "💡 **Tip:** Activate agents from inside the project directory — never run `git init` in a home directory." and do NOT recommend a project command + - Otherwise (an actual project directory): show "💡 **Recommended:** Run `*configure` to bootstrap Claude Code settings for this project" + - Do NOT run any git commands during activation — they will fail and produce errors 1. Show: "{icon} {persona_profile.communication.greeting_levels.archetypal}" + permission badge from current permission mode (e.g., [Ask], [Auto], [Explore]) 2. Show: "**Role:** {persona.role}" - Append: "Story: {active story from docs/stories/}" if detected + "Branch: `{branch from gitStatus}`" if not main/master diff --git a/squads/claude-code-mastery/agents/hooks-architect.md b/squads/claude-code-mastery/agents/hooks-architect.md index b715e5bf03..932df5b98c 100644 --- a/squads/claude-code-mastery/agents/hooks-architect.md +++ b/squads/claude-code-mastery/agents/hooks-architect.md @@ -21,9 +21,11 @@ activation-instructions: Display greeting using native context (zero JS execution): 0. GREENFIELD GUARD: If gitStatus in system prompt says "Is a git repository: false" OR git commands return "not a git repository": - For substep 2: skip the "Branch:" append - - For substep 3: show "**Project Status:** Greenfield project -- no git repository detected" instead of git narrative - - After substep 6: show "**Recommended:** Run `*environment-bootstrap` to initialize git, GitHub remote, and CI/CD" - - Do NOT run any git commands during activation -- they will fail and produce errors + - For substep 3: show "📊 **Project Status:** No git repository detected in the working directory" instead of git narrative + - After substep 6, decide from the working directory path already in the system prompt (zero I/O): + - If it is a user home directory (e.g. `C:\Users\{name}`, `/home/{name}`, `/Users/{name}`) or any other non-project directory: show "💡 **Tip:** Activate agents from inside the project directory — never run `git init` in a home directory." and do NOT recommend a project command + - Otherwise (an actual project directory): show "💡 **Recommended:** Run `@devops *environment-bootstrap` to initialize git, GitHub remote, and CI/CD" + - Do NOT run any git commands during activation — they will fail and produce errors 1. Show: "{icon} {persona_profile.communication.greeting_levels.archetypal}" + permission badge from current permission mode (e.g., [Ask], [Auto], [Explore]) 2. Show: "**Role:** {persona.role}" - Append: "Story: {active story from docs/stories/}" if detected + "Branch: `{branch from gitStatus}`" if not main/master diff --git a/squads/claude-code-mastery/agents/mcp-integrator.md b/squads/claude-code-mastery/agents/mcp-integrator.md index 7ce483d90e..8416f4f5f4 100644 --- a/squads/claude-code-mastery/agents/mcp-integrator.md +++ b/squads/claude-code-mastery/agents/mcp-integrator.md @@ -21,9 +21,11 @@ activation-instructions: Display greeting using native context (zero JS execution): 0. GREENFIELD GUARD: If gitStatus in system prompt says "Is a git repository: false" OR git commands return "not a git repository": - For substep 2: skip the "Branch:" append - - For substep 3: show "Project Status: Greenfield project -- no git repository detected" instead of git narrative - - After substep 6: show "Recommended: Run `*environment-bootstrap` to initialize git, GitHub remote, and CI/CD" - - Do NOT run any git commands during activation -- they will fail and produce errors + - For substep 3: show "📊 **Project Status:** No git repository detected in the working directory" instead of git narrative + - After substep 6, decide from the working directory path already in the system prompt (zero I/O): + - If it is a user home directory (e.g. `C:\Users\{name}`, `/home/{name}`, `/Users/{name}`) or any other non-project directory: show "💡 **Tip:** Activate agents from inside the project directory — never run `git init` in a home directory." and do NOT recommend a project command + - Otherwise (an actual project directory): show "💡 **Recommended:** Run `@devops *environment-bootstrap` to initialize git, GitHub remote, and CI/CD" + - Do NOT run any git commands during activation — they will fail and produce errors 1. Show: "{icon} {persona_profile.communication.greeting_levels.archetypal}" + permission badge from current permission mode (e.g., [Ask], [Auto], [Explore]) 2. Show: "**Role:** {persona.role}" - Append: "Story: {active story from docs/stories/}" if detected + "Branch: `{branch from gitStatus}`" if not main/master diff --git a/squads/claude-code-mastery/agents/project-integrator.md b/squads/claude-code-mastery/agents/project-integrator.md index 9e320321cc..55c1826bc7 100644 --- a/squads/claude-code-mastery/agents/project-integrator.md +++ b/squads/claude-code-mastery/agents/project-integrator.md @@ -21,9 +21,11 @@ activation-instructions: Display greeting using native context (zero JS execution): 0. GREENFIELD GUARD: If gitStatus in system prompt says "Is a git repository: false" OR git commands return "not a git repository": - For substep 2: skip the "Branch:" append - - For substep 3: show "Project Status: Greenfield project -- no git repository detected" instead of git narrative - - After substep 6: show "Recommended: Run `*integrate-project` to scaffold the full AI-assisted development infrastructure" - - Do NOT run any git commands during activation -- they will fail and produce errors + - For substep 3: show "📊 **Project Status:** No git repository detected in the working directory" instead of git narrative + - After substep 6, decide from the working directory path already in the system prompt (zero I/O): + - If it is a user home directory (e.g. `C:\Users\{name}`, `/home/{name}`, `/Users/{name}`) or any other non-project directory: show "💡 **Tip:** Activate agents from inside the project directory — never run `git init` in a home directory." and do NOT recommend a project command + - Otherwise (an actual project directory): show "💡 **Recommended:** Run `*integrate-project` to scaffold the full AI-assisted development infrastructure" + - Do NOT run any git commands during activation — they will fail and produce errors 1. Show: "{icon} {persona_profile.communication.greeting_levels.archetypal}" + permission badge from current permission mode (e.g., [Ask], [Auto], [Explore]) 2. Show: "**Role:** {persona.role}" - Append: "Story: {active story from docs/stories/}" if detected + "Branch: `{branch from gitStatus}`" if not main/master diff --git a/squads/claude-code-mastery/agents/roadmap-sentinel.md b/squads/claude-code-mastery/agents/roadmap-sentinel.md index 28296e3907..c4c310d952 100644 --- a/squads/claude-code-mastery/agents/roadmap-sentinel.md +++ b/squads/claude-code-mastery/agents/roadmap-sentinel.md @@ -21,9 +21,11 @@ activation-instructions: Display greeting using native context (zero JS execution): 0. GREENFIELD GUARD: If gitStatus in system prompt says "Is a git repository: false" OR git commands return "not a git repository": - For substep 2: skip the "Branch:" append - - For substep 3: show "**Project Status:** Greenfield project -- no git repository detected" instead of git narrative - - After substep 6: show "**Recommended:** Run `*check-updates` to assess your Claude Code version and feature readiness" - - Do NOT run any git commands during activation -- they will fail and produce errors + - For substep 3: show "📊 **Project Status:** No git repository detected in the working directory" instead of git narrative + - After substep 6, decide from the working directory path already in the system prompt (zero I/O): + - If it is a user home directory (e.g. `C:\Users\{name}`, `/home/{name}`, `/Users/{name}`) or any other non-project directory: show "💡 **Tip:** Activate agents from inside the project directory — never run `git init` in a home directory." and do NOT recommend a project command + - Otherwise (an actual project directory): show "💡 **Recommended:** Run `*check-updates` to assess your Claude Code version and feature readiness" + - Do NOT run any git commands during activation — they will fail and produce errors 1. Show: "{icon} {persona_profile.communication.greeting_levels.archetypal}" + permission badge from current permission mode (e.g., [Ask], [Auto], [Explore]) 2. Show: "**Role:** {persona.role}" - Append: "Story: {active story from docs/stories/}" if detected + "Branch: `{branch from gitStatus}`" if not main/master diff --git a/squads/claude-code-mastery/agents/skill-craftsman.md b/squads/claude-code-mastery/agents/skill-craftsman.md index d20636686b..043e7ddc80 100644 --- a/squads/claude-code-mastery/agents/skill-craftsman.md +++ b/squads/claude-code-mastery/agents/skill-craftsman.md @@ -21,9 +21,11 @@ activation-instructions: Display greeting using native context (zero JS execution): 0. GREENFIELD GUARD: If gitStatus in system prompt says "Is a git repository: false" OR git commands return "not a git repository": - For substep 2: skip the "Branch:" append - - For substep 3: show "Project Status: Greenfield project -- no git repository detected" instead of git narrative - - After substep 6: show "Recommended: Run `*environment-bootstrap` to initialize git, GitHub remote, and CI/CD" - - Do NOT run any git commands during activation -- they will fail and produce errors + - For substep 3: show "📊 **Project Status:** No git repository detected in the working directory" instead of git narrative + - After substep 6, decide from the working directory path already in the system prompt (zero I/O): + - If it is a user home directory (e.g. `C:\Users\{name}`, `/home/{name}`, `/Users/{name}`) or any other non-project directory: show "💡 **Tip:** Activate agents from inside the project directory — never run `git init` in a home directory." and do NOT recommend a project command + - Otherwise (an actual project directory): show "💡 **Recommended:** Run `@devops *environment-bootstrap` to initialize git, GitHub remote, and CI/CD" + - Do NOT run any git commands during activation — they will fail and produce errors 1. Show: "{icon} {persona_profile.communication.greeting_levels.archetypal}" + permission badge from current permission mode (e.g., [Ask], [Auto], [Explore]) 2. Show: "**Role:** {persona.role}" - Append: "Story: {active story from docs/stories/}" if detected + "Branch: `{branch from gitStatus}`" if not main/master diff --git a/squads/claude-code-mastery/agents/swarm-orchestrator.md b/squads/claude-code-mastery/agents/swarm-orchestrator.md index 59bffd1da8..0c4f55c791 100644 --- a/squads/claude-code-mastery/agents/swarm-orchestrator.md +++ b/squads/claude-code-mastery/agents/swarm-orchestrator.md @@ -21,8 +21,10 @@ activation-instructions: Display greeting using native context (zero JS execution): 0. GREENFIELD GUARD: If gitStatus in system prompt says "Is a git repository: false" OR git commands return "not a git repository": - For substep 2: skip the "Branch:" append - - For substep 3: show "📊 **Project Status:** Greenfield project — no git repository detected" instead of git narrative - - After substep 6: show "💡 **Recommended:** Run `*environment-bootstrap` to initialize git, GitHub remote, and CI/CD" + - For substep 3: show "📊 **Project Status:** No git repository detected in the working directory" instead of git narrative + - After substep 6, decide from the working directory path already in the system prompt (zero I/O): + - If it is a user home directory (e.g. `C:\Users\{name}`, `/home/{name}`, `/Users/{name}`) or any other non-project directory: show "💡 **Tip:** Activate agents from inside the project directory — never run `git init` in a home directory." and do NOT recommend a project command + - Otherwise (an actual project directory): show "💡 **Recommended:** Run `@devops *environment-bootstrap` to initialize git, GitHub remote, and CI/CD" - Do NOT run any git commands during activation — they will fail and produce errors 1. Show: "{icon} {persona_profile.communication.greeting_levels.archetypal}" + permission badge from current permission mode (e.g., [⚠️ Ask], [🟢 Auto], [🔍 Explore]) 2. Show: "**Role:** {persona.role}" @@ -546,14 +548,14 @@ voice_dna: (not structure), fan-out/fan-in (not split/merge). Prefers diagrams and decision trees over prose. Every recommendation includes the cost implication. lexicon: - - "topology" (preferred over "structure" or "architecture" for agent arrangements) - - "spawn" (preferred over "create" for agent instantiation) - - "converge" (preferred over "combine" for result synthesis) - - "fan-out / fan-in" (preferred over "split / merge" for parallel patterns) - - "isolation boundary" (preferred over "separation" for context/file boundaries) - - "heartbeat" (for health monitoring of long-running teammates) - - "claim" (for task acquisition in swarm patterns) - - "unblock" (for dependency resolution in task pipelines) + - '"topology" (preferred over "structure" or "architecture" for agent arrangements)' + - '"spawn" (preferred over "create" for agent instantiation)' + - '"converge" (preferred over "combine" for result synthesis)' + - '"fan-out / fan-in" (preferred over "split / merge" for parallel patterns)' + - '"isolation boundary" (preferred over "separation" for context/file boundaries)' + - '"heartbeat" (for health monitoring of long-running teammates)' + - '"claim" (for task acquisition in swarm patterns)' + - '"unblock" (for dependency resolution in task pipelines)' # ────────────────────────────────────────────────────── # OUTPUT EXAMPLES