@esquadrao/cli 0.0.0-stage → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +366 -2
  3. package/assets/fonts/Anton-Regular.ttf +0 -0
  4. package/assets/fonts/BebasNeue-Regular.ttf +0 -0
  5. package/assets/fonts/OFL.txt +93 -0
  6. package/assets/fonts/Poppins-Bold.ttf +0 -0
  7. package/assets/fonts/README.md +13 -0
  8. package/bin/cli.js +126 -0
  9. package/package.json +58 -4
  10. package/scripts/ast_slice.js +73 -0
  11. package/scripts/cutout.py +197 -0
  12. package/scripts/dag_validator.js +78 -0
  13. package/scripts/lint.js +43 -0
  14. package/scripts/merkle_verify.js +83 -0
  15. package/scripts/wcag_check.js +77 -0
  16. package/skill-audit/SKILL.md +42 -0
  17. package/skill-audit/references/merkle-ledger-spec.md +27 -0
  18. package/skill-audit/references/receipt-ed25519-verification.md +17 -0
  19. package/skill-audit/references/time-travel-replay.md +10 -0
  20. package/skill-code-reviewer/SKILL.md +40 -0
  21. package/skill-context/SKILL.md +44 -0
  22. package/skill-context/references/ast-virtualization.md +10 -0
  23. package/skill-context/references/openapi-contract-synthesis.md +10 -0
  24. package/skill-engineering-manager/SKILL.md +40 -0
  25. package/skill-media-producer/SKILL.md +328 -0
  26. package/skill-media-producer/references/caption-templates.md +194 -0
  27. package/skill-media-producer/references/composicoes-especiais.md +99 -0
  28. package/skill-media-producer/references/configuracao-inicial.md +239 -0
  29. package/skill-media-producer/references/corte-podcast-3-niveis.md +179 -0
  30. package/skill-media-producer/references/llm-agent-guide.md +231 -0
  31. package/skill-orchestrate/SKILL.md +49 -0
  32. package/skill-orchestrate/references/mission-lifecycle.md +36 -0
  33. package/skill-orchestrate/references/swarm-coordination.md +33 -0
  34. package/skill-pipeline/SKILL.md +42 -0
  35. package/skill-pipeline/references/auto-healing-patterns.md +17 -0
  36. package/skill-pipeline/references/dag-decomposition-rules.md +18 -0
  37. package/skill-pipeline/references/topological-waves.md +16 -0
  38. package/skill-product-manager/SKILL.md +40 -0
  39. package/skill-qa-engineer/SKILL.md +40 -0
  40. package/skill-review/SKILL.md +46 -0
  41. package/skill-review/references/anti-slop-patterns.md +17 -0
  42. package/skill-review/references/dual-blind-adjudication.md +15 -0
  43. package/skill-review/references/voice-calibration.md +10 -0
  44. package/skill-security-engineer/SKILL.md +40 -0
  45. package/skill-software-architect/SKILL.md +40 -0
  46. package/skill-software-engineer/SKILL.md +40 -0
  47. package/skill-sre-engineer/SKILL.md +40 -0
  48. package/skill-system-analyst/SKILL.md +40 -0
  49. package/skill-tech-lead/SKILL.md +40 -0
  50. package/skill-technical-writer/SKILL.md +40 -0
  51. package/skill-ui/SKILL.md +45 -0
  52. package/skill-ui/references/design-tokens-spec.md +19 -0
  53. package/skill-ui/references/visual-tdd-methodology.md +10 -0
  54. package/skill-ui/references/wcag-target-sizes.md +9 -0
  55. package/src/captionTemplates.js +285 -0
  56. package/src/commands/onboard.js +618 -0
  57. package/src/commands/role.js +119 -0
  58. package/src/commands/setup.js +174 -0
  59. package/src/commands/studio.js +1822 -0
  60. package/src/roles/authority.js +129 -0
  61. package/src/roles/codeReviewer.js +65 -0
  62. package/src/roles/engineeringManager.js +53 -0
  63. package/src/roles/index.js +80 -0
  64. package/src/roles/mediaProducer.js +223 -0
  65. package/src/roles/productManager.js +50 -0
  66. package/src/roles/qaEngineer.js +54 -0
  67. package/src/roles/securityEngineer.js +53 -0
  68. package/src/roles/softwareArchitect.js +58 -0
  69. package/src/roles/softwareEngineer.js +76 -0
  70. package/src/roles/sreEngineer.js +60 -0
  71. package/src/roles/systemAnalyst.js +45 -0
  72. package/src/roles/techLead.js +46 -0
  73. package/src/roles/technicalWriter.js +46 -0
@@ -0,0 +1,119 @@
1
+ // CLI command: esquadrao role [list|info|prompt|matrix]
2
+ import { listRoles, getRole, READ_ONLY_ROLES, FORBIDDEN_COMMAND_PATTERNS } from '../roles/index.js';
3
+
4
+ export async function run({ positionals = [], flags = {} } = {}) {
5
+ const sub = positionals[0] || 'list';
6
+
7
+ if (flags.help || sub === 'help') {
8
+ console.log(`Esquadrão Roles Command
9
+
10
+ Usage:
11
+ esquadrao role [subcommand] [arguments] [options]
12
+
13
+ Subcommands:
14
+ list List all standard industry engineering roles (default)
15
+ info <id> Display role specification, capabilities, and authority
16
+ prompt <id> Generate calibrated prompt for an agent role
17
+ matrix Display structural authority matrix and permission boundaries
18
+
19
+ Options:
20
+ --json Output results in JSON format
21
+ -h, --help Show this help message`);
22
+ return;
23
+ }
24
+
25
+ if (sub === 'list') {
26
+ const roles = listRoles();
27
+ if (flags.json) {
28
+ console.log(JSON.stringify(roles, null, 2));
29
+ return;
30
+ }
31
+ console.log('Roles Matrix:\n');
32
+ for (const r of roles) {
33
+ const roTag = r.readOnly ? '[READ-ONLY]' : '[READ/WRITE]';
34
+ console.log(` ${r.id.padEnd(22)} ${roTag.padEnd(14)} ${r.title}`);
35
+ console.log(` Description: ${r.description}`);
36
+ console.log(` Capabilities: ${r.requiredCapabilities.join(', ')}`);
37
+ if (r.formerName) console.log(` Former name: ${r.formerName}`);
38
+ console.log('');
39
+ }
40
+ return;
41
+ }
42
+
43
+ if (sub === 'info') {
44
+ const target = positionals[1];
45
+ if (!target) {
46
+ console.error('Error: Missing role identifier. Usage: esquadrao role info <role_id>');
47
+ process.exit(1);
48
+ }
49
+ const roleMod = getRole(target);
50
+ if (!roleMod) {
51
+ console.error(`Error: Unknown role '${target}'. Run 'esquadrao role list' to see available roles.`);
52
+ process.exit(1);
53
+ }
54
+ if (flags.json) {
55
+ console.log(JSON.stringify(roleMod.definition, null, 2));
56
+ return;
57
+ }
58
+ const def = roleMod.definition;
59
+ console.log(`Role Specification: ${def.title} (${def.id})`);
60
+ console.log(`--------------------------------------------------`);
61
+ console.log(`Category: ${def.category}`);
62
+ console.log(`Access: ${def.readOnly ? 'Strictly Read-Only' : 'Read/Write'}`);
63
+ console.log(`Capabilities: ${def.requiredCapabilities.join(', ')}`);
64
+ console.log(`Allowed Outputs: ${def.allowedOutputPrefixes.join(', ')}`);
65
+ if (def.formerName) console.log(`Former Alias: ${def.formerName}`);
66
+ console.log(`\nDescription:\n ${def.description}`);
67
+ return;
68
+ }
69
+
70
+ if (sub === 'prompt') {
71
+ const target = positionals[1];
72
+ if (!target) {
73
+ console.error('Error: Missing role identifier. Usage: esquadrao role prompt <role_id> [intent]');
74
+ process.exit(1);
75
+ }
76
+ const roleMod = getRole(target);
77
+ if (!roleMod) {
78
+ console.error(`Error: Unknown role '${target}'.`);
79
+ process.exit(1);
80
+ }
81
+ const intent = positionals.slice(2).join(' ') || 'Fulfill the primary engineering task.';
82
+ const prompt = roleMod.buildPrompt({ intent, objective: intent });
83
+ if (flags.json) {
84
+ console.log(JSON.stringify({ role: roleMod.definition.id, prompt }, null, 2));
85
+ return;
86
+ }
87
+ console.log(prompt);
88
+ return;
89
+ }
90
+
91
+ if (sub === 'matrix') {
92
+ const matrix = {
93
+ readOnlyRoles: Array.from(READ_ONLY_ROLES),
94
+ forbiddenPatterns: FORBIDDEN_COMMAND_PATTERNS.map((p) => p.source),
95
+ roles: listRoles().map((r) => ({
96
+ id: r.id,
97
+ title: r.title,
98
+ readOnly: r.readOnly,
99
+ allowedPrefixes: r.allowedOutputPrefixes,
100
+ })),
101
+ };
102
+ if (flags.json) {
103
+ console.log(JSON.stringify(matrix, null, 2));
104
+ return;
105
+ }
106
+ console.log('Structural Authority Matrix:\n');
107
+ console.log(`Read-Only Roles: ${matrix.readOnlyRoles.join(', ')}`);
108
+ console.log(`Forbidden Command Patterns:\n${matrix.forbiddenPatterns.map((p) => ` - ${p}`).join('\n')}\n`);
109
+ for (const r of matrix.roles) {
110
+ console.log(`- ${r.id.padEnd(20)} ${r.readOnly ? 'RO' : 'RW'} (Outputs: ${r.allowedPrefixes.join(', ')})`);
111
+ }
112
+ return;
113
+ }
114
+
115
+ console.error(`Unknown subcommand '${sub}'. Run 'esquadrao role --help' for usage.`);
116
+ process.exit(1);
117
+ }
118
+
119
+ export default run;
@@ -0,0 +1,174 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import os from 'node:os';
4
+ import { fileURLToPath } from 'node:url';
5
+ import { execSync } from 'node:child_process';
6
+
7
+ function checkBinary(name) {
8
+ try {
9
+ const cmd = process.platform === 'win32' ? `where ${name}` : `which ${name}`;
10
+ execSync(cmd, { stdio: 'ignore' });
11
+ return true;
12
+ } catch {
13
+ return false;
14
+ }
15
+ }
16
+
17
+ export function tryAutoInstallFfmpeg() {
18
+ if (checkBinary('ffmpeg') && checkBinary('ffprobe')) return true;
19
+ try {
20
+ if (process.platform === 'darwin') {
21
+ execSync('brew install ffmpeg', { stdio: 'ignore', timeout: 60000 });
22
+ } else if (process.platform === 'win32') {
23
+ execSync('winget install Gyan.FFmpeg --accept-package-agreements --accept-source-agreements', { stdio: 'ignore', timeout: 60000 });
24
+ } else {
25
+ execSync('which apt-get && (apt-get update -qq && apt-get install -y -qq ffmpeg) || sudo apt-get update -qq && sudo apt-get install -y -qq ffmpeg', { stdio: 'ignore', timeout: 60000 });
26
+ }
27
+ return checkBinary('ffmpeg') && checkBinary('ffprobe');
28
+ } catch {
29
+ return false;
30
+ }
31
+ }
32
+
33
+ const SKILLS = [
34
+ 'skill-orchestrate',
35
+ 'skill-pipeline',
36
+ 'skill-review',
37
+ 'skill-audit',
38
+ 'skill-context',
39
+ 'skill-ui',
40
+ 'skill-product-manager',
41
+ 'skill-system-analyst',
42
+ 'skill-software-architect',
43
+ 'skill-tech-lead',
44
+ 'skill-security-engineer',
45
+ 'skill-software-engineer',
46
+ 'skill-code-reviewer',
47
+ 'skill-sre-engineer',
48
+ 'skill-qa-engineer',
49
+ 'skill-technical-writer',
50
+ 'skill-engineering-manager',
51
+ 'skill-media-producer',
52
+ ];
53
+
54
+ // ponytail: synchronous copy; upgrade to async workers when syncing >50 skills
55
+ export async function run({ positionals = [], flags = {} } = {}) {
56
+ if (flags?.help) {
57
+ console.log('Usage: esquadrao setup [--dest <path>] [--json]');
58
+ return;
59
+ }
60
+
61
+ const rootDir = fileURLToPath(new URL('../../', import.meta.url));
62
+ const cwd = process.cwd();
63
+ const destArg = typeof flags?.dest === 'string' ? flags.dest : (positionals[0] || null);
64
+ const destDir = destArg || path.join(cwd, '.agents', 'skills');
65
+
66
+ fs.mkdirSync(destDir, { recursive: true });
67
+ const installed = [];
68
+ for (const item of [...SKILLS, 'scripts']) {
69
+ const src = path.join(rootDir, item);
70
+ if (fs.existsSync(src)) {
71
+ fs.cpSync(src, path.join(destDir, item), { recursive: true });
72
+ installed.push(item);
73
+ }
74
+ }
75
+
76
+ const harnesses = [];
77
+
78
+ // If a custom destination was not explicitly passed, configure local project harnesses
79
+ if (!destArg) {
80
+ // 1. Grok Build / Agent Skills
81
+ if (fs.existsSync(path.join(cwd, '.agents'))) {
82
+ harnesses.push('.agents');
83
+ }
84
+
85
+ // 2. Claude Code
86
+ const claudeDir = path.join(cwd, '.claude');
87
+ if (fs.existsSync(claudeDir)) {
88
+ harnesses.push('.claude');
89
+ const claudeSkillsDir = path.join(claudeDir, 'skills');
90
+ fs.mkdirSync(claudeSkillsDir, { recursive: true });
91
+ for (const item of [...SKILLS, 'scripts']) {
92
+ const src = path.join(rootDir, item);
93
+ if (fs.existsSync(src)) {
94
+ fs.cpSync(src, path.join(claudeSkillsDir, item), { recursive: true });
95
+ }
96
+ }
97
+ }
98
+
99
+ // 3. Codex CLI (detects .codex or ~/.codex or AGENTS.md)
100
+ const codexDir = path.join(cwd, '.codex');
101
+ const userCodex = path.join(os.homedir(), '.codex');
102
+ if (fs.existsSync(codexDir) || fs.existsSync(userCodex) || fs.existsSync(path.join(cwd, 'AGENTS.md'))) {
103
+ harnesses.push('.codex');
104
+ const codexSkillsDir = path.join(codexDir, 'skills');
105
+ fs.mkdirSync(codexSkillsDir, { recursive: true });
106
+ for (const item of [...SKILLS, 'scripts']) {
107
+ const src = path.join(rootDir, item);
108
+ if (fs.existsSync(src)) {
109
+ fs.cpSync(src, path.join(codexSkillsDir, item), { recursive: true });
110
+ }
111
+ }
112
+
113
+ // Ensure AGENTS.md references the skills
114
+ const agentsMdPath = path.join(cwd, 'AGENTS.md');
115
+ if (!fs.existsSync(agentsMdPath)) {
116
+ fs.writeFileSync(
117
+ agentsMdPath,
118
+ '# Agent Instructions\n\nSkills are installed in `.codex/skills/` and `.agents/skills/`.\n'
119
+ );
120
+ }
121
+ }
122
+
123
+ // 4. Cursor Rules (.cursor/rules/*.mdc)
124
+ const cursorDir = path.join(cwd, '.cursor');
125
+ if (fs.existsSync(cursorDir)) {
126
+ harnesses.push('.cursor');
127
+ const rulesDir = path.join(cursorDir, 'rules');
128
+ fs.mkdirSync(rulesDir, { recursive: true });
129
+ fs.writeFileSync(
130
+ path.join(rulesDir, 'esquadrao.mdc'),
131
+ '---\ndescription: Esquadrao Skills Rules\nglobs: *\n---\nUse esquadrao tools and CLI.\n'
132
+ );
133
+ }
134
+
135
+ // 5. VS Code
136
+ if (fs.existsSync(path.join(cwd, '.vscode'))) harnesses.push('.vscode');
137
+
138
+ // 6. Hermes
139
+ if (fs.existsSync(path.join(os.homedir(), '.hermes'))) harnesses.push('.hermes');
140
+ }
141
+
142
+ const nodeMajor = parseInt(process.versions.node.split('.')[0], 10);
143
+ const nodeOk = nodeMajor >= 18;
144
+
145
+ let hasFfmpeg = checkBinary('ffmpeg') && checkBinary('ffprobe');
146
+ let autoInstalledFfmpeg = false;
147
+ if (!hasFfmpeg) {
148
+ autoInstalledFfmpeg = tryAutoInstallFfmpeg();
149
+ hasFfmpeg = checkBinary('ffmpeg') && checkBinary('ffprobe');
150
+ }
151
+
152
+ const report = {
153
+ status: nodeOk ? 'ok' : 'degraded',
154
+ prerequisites: {
155
+ node: { version: process.version, valid: nodeOk },
156
+ ffmpeg: { valid: hasFfmpeg, auto_installed: autoInstalledFfmpeg }
157
+ },
158
+ installation: { destination: destDir, installed },
159
+ harnesses,
160
+ };
161
+
162
+ if (flags?.json) {
163
+ console.log(JSON.stringify(report));
164
+ } else {
165
+ console.log(`Esquadrão Setup: ${report.status.toUpperCase()}`);
166
+ console.log(`- Node.js: ${process.version} (${nodeOk ? 'OK' : 'Requires >= 18'})`);
167
+ console.log(`- FFmpeg & ffprobe: ${hasFfmpeg ? (autoInstalledFfmpeg ? 'Instalado automaticamente com sucesso!' : 'OK') : 'Pendente (peça ao seu agente de IA: "instale o ffmpeg para mim")'}`);
168
+ console.log(`- Installed ${installed.length} items to ${destDir}`);
169
+ if (harnesses.length) console.log(`- Harnesses detected: ${harnesses.join(', ')}`);
170
+ }
171
+ return report;
172
+ }
173
+
174
+ export default run;