grimoire-framework 1.0.21 → 1.1.1
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.
- package/.grimoire/install-manifest.yaml +2 -2
- package/bin/commands/marketplace.js +304 -0
- package/bin/commands/pro.js +237 -0
- package/bin/grimoire-cli.js +69 -20
- package/marketplace/agents/api-designer.md +56 -0
- package/marketplace/agents/database-expert.md +56 -0
- package/marketplace/agents/frontend-specialist.md +55 -0
- package/marketplace/agents/ml-engineer.md +55 -0
- package/marketplace/agents/security-auditor.md +55 -0
- package/marketplace/agents/tech-writer.md +56 -0
- package/marketplace/registry.json +96 -0
- package/package.json +2 -1
- package/scripts/pre-publish-check.js +30 -1
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
# - SHA256 hashes for change detection
|
|
8
8
|
# - File types for categorization
|
|
9
9
|
#
|
|
10
|
-
version: 1.
|
|
11
|
-
generated_at: "2026-02-
|
|
10
|
+
version: 1.1.1
|
|
11
|
+
generated_at: "2026-02-22T15:03:35.007Z"
|
|
12
12
|
generator: scripts/generate-install-manifest.js
|
|
13
13
|
file_count: 1011
|
|
14
14
|
files:
|
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* grimoire marketplace — Community Agent Registry
|
|
3
|
+
*
|
|
4
|
+
* grimoire marketplace list Navega agentes da comunidade
|
|
5
|
+
* grimoire marketplace install <slug> Instala um agente do marketplace
|
|
6
|
+
* grimoire marketplace search <term> Busca por especialidade ou tag
|
|
7
|
+
* grimoire marketplace submit Instruções para publicar seu agente
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
'use strict';
|
|
11
|
+
|
|
12
|
+
const path = require('path');
|
|
13
|
+
const fs = require('fs');
|
|
14
|
+
const https = require('https');
|
|
15
|
+
const os = require('os');
|
|
16
|
+
|
|
17
|
+
// ── Curated registry (built-in fallback, also fetched from GitHub) ─────────────
|
|
18
|
+
const REGISTRY_URL = 'https://raw.githubusercontent.com/gabrielrlima/grimoire/master/marketplace/registry.json';
|
|
19
|
+
const CACHE_FILE = path.join(os.homedir(), '.grimoire-marketplace-cache.json');
|
|
20
|
+
const CACHE_TTL_MINS = 60; // 1 hour
|
|
21
|
+
|
|
22
|
+
const BUILTIN_AGENTS = [
|
|
23
|
+
{
|
|
24
|
+
slug: 'frontend-specialist',
|
|
25
|
+
name: 'Botticelli',
|
|
26
|
+
icon: '🎠',
|
|
27
|
+
specialty: 'Frontend & UI/UX',
|
|
28
|
+
tags: ['react', 'css', 'typescript', 'nextjs'],
|
|
29
|
+
author: 'grimoire-team',
|
|
30
|
+
description: 'Especialista em React, TypeScript e design systems. Ideal para times com foco em UI.',
|
|
31
|
+
gist: 'https://raw.githubusercontent.com/gabrielrlima/grimoire/master/marketplace/agents/frontend-specialist.md',
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
slug: 'security-auditor',
|
|
35
|
+
name: 'Rembrandt',
|
|
36
|
+
icon: '🔐',
|
|
37
|
+
specialty: 'Segurança & Auditoria',
|
|
38
|
+
tags: ['security', 'owasp', 'pentest', 'audit'],
|
|
39
|
+
author: 'grimoire-team',
|
|
40
|
+
description: 'Audita código em busca de vulnerabilidades OWASP Top 10. SAST e code review de segurança.',
|
|
41
|
+
gist: 'https://raw.githubusercontent.com/gabrielrlima/grimoire/master/marketplace/agents/security-auditor.md',
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
slug: 'ml-engineer',
|
|
45
|
+
name: 'Dalí',
|
|
46
|
+
icon: '🧠',
|
|
47
|
+
specialty: 'Machine Learning & AI',
|
|
48
|
+
tags: ['ml', 'python', 'pytorch', 'sklearn'],
|
|
49
|
+
author: 'grimoire-team',
|
|
50
|
+
description: 'Implementa pipelines de ML, feature engineering, treinamento e avaliação de modelos.',
|
|
51
|
+
gist: 'https://raw.githubusercontent.com/gabrielrlima/grimoire/master/marketplace/agents/ml-engineer.md',
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
slug: 'api-designer',
|
|
55
|
+
name: 'Klimt',
|
|
56
|
+
icon: '🔗',
|
|
57
|
+
specialty: 'API Design & Documentação',
|
|
58
|
+
tags: ['rest', 'graphql', 'openapi', 'swagger'],
|
|
59
|
+
author: 'grimoire-team',
|
|
60
|
+
description: 'Projeta APIs RESTful e GraphQL. Gera documentação OpenAPI 3.x e valida contratos.',
|
|
61
|
+
gist: 'https://raw.githubusercontent.com/gabrielrlima/grimoire/master/marketplace/agents/api-designer.md',
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
slug: 'database-expert',
|
|
65
|
+
name: 'Mondrian',
|
|
66
|
+
icon: '🗄️',
|
|
67
|
+
specialty: 'Banco de Dados & Queries',
|
|
68
|
+
tags: ['sql', 'postgresql', 'mongodb', 'redis'],
|
|
69
|
+
author: 'grimoire-team',
|
|
70
|
+
description: 'Otimiza queries, projeta schemas e revisa migrações. PostgreSQL, MongoDB, Redis.',
|
|
71
|
+
gist: 'https://raw.githubusercontent.com/gabrielrlima/grimoire/master/marketplace/agents/database-expert.md',
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
slug: 'tech-writer',
|
|
75
|
+
name: 'Cervantes',
|
|
76
|
+
icon: '✍️',
|
|
77
|
+
specialty: 'Documentação Técnica',
|
|
78
|
+
tags: ['docs', 'readme', 'adr', 'wiki'],
|
|
79
|
+
author: 'grimoire-team',
|
|
80
|
+
description: 'Escreve e revisa documentação técnica: READMEs, ADRs, guias de API e wikis.',
|
|
81
|
+
gist: 'https://raw.githubusercontent.com/gabrielrlima/grimoire/master/marketplace/agents/tech-writer.md',
|
|
82
|
+
},
|
|
83
|
+
];
|
|
84
|
+
|
|
85
|
+
// ── Fetcher ────────────────────────────────────────────────────────────────────
|
|
86
|
+
async function fetchRegistry() {
|
|
87
|
+
// Use cache if fresh
|
|
88
|
+
if (fs.existsSync(CACHE_FILE)) {
|
|
89
|
+
try {
|
|
90
|
+
const cache = JSON.parse(fs.readFileSync(CACHE_FILE, 'utf8'));
|
|
91
|
+
const minsSince = (Date.now() - cache.ts) / 60000;
|
|
92
|
+
if (minsSince < CACHE_TTL_MINS) return cache.agents;
|
|
93
|
+
} catch (_) { }
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Try to fetch remote registry
|
|
97
|
+
try {
|
|
98
|
+
const remote = await new Promise((resolve, reject) => {
|
|
99
|
+
const req = https.get(REGISTRY_URL, { timeout: 4000 }, (res) => {
|
|
100
|
+
let body = '';
|
|
101
|
+
res.on('data', d => body += d);
|
|
102
|
+
res.on('end', () => { try { resolve(JSON.parse(body)); } catch (e) { reject(e); } });
|
|
103
|
+
});
|
|
104
|
+
req.on('error', reject);
|
|
105
|
+
req.on('timeout', () => req.destroy());
|
|
106
|
+
});
|
|
107
|
+
const agents = remote.agents || BUILTIN_AGENTS;
|
|
108
|
+
fs.writeFileSync(CACHE_FILE, JSON.stringify({ ts: Date.now(), agents }), 'utf8');
|
|
109
|
+
return agents;
|
|
110
|
+
} catch (_) {
|
|
111
|
+
// Fall back to built-in
|
|
112
|
+
return BUILTIN_AGENTS;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// ── Commands ───────────────────────────────────────────────────────────────────
|
|
117
|
+
async function run(args) {
|
|
118
|
+
const sub = args[0];
|
|
119
|
+
switch (sub) {
|
|
120
|
+
case 'install': await installAgent(args[1]); break;
|
|
121
|
+
case 'search': await searchAgents(args.slice(1)); break;
|
|
122
|
+
case 'submit': showSubmitGuide(); break;
|
|
123
|
+
case 'list':
|
|
124
|
+
default: await listAgents(args); break;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// ── List ───────────────────────────────────────────────────────────────────────
|
|
129
|
+
async function listAgents(args) {
|
|
130
|
+
process.stdout.write('🔍 Carregando registry...');
|
|
131
|
+
const agents = await fetchRegistry();
|
|
132
|
+
const tagFilter = args.find(a => a.startsWith('--tag='));
|
|
133
|
+
const filtered = tagFilter
|
|
134
|
+
? agents.filter(a => a.tags.includes(tagFilter.replace('--tag=', '')))
|
|
135
|
+
: agents;
|
|
136
|
+
|
|
137
|
+
console.log(`\r\n🏪 Grimoire Marketplace — ${filtered.length} agentes disponíveis\n`);
|
|
138
|
+
console.log(' ' + '─'.repeat(60));
|
|
139
|
+
|
|
140
|
+
filtered.forEach(agent => {
|
|
141
|
+
const tags = agent.tags.slice(0, 3).map(t => `#${t}`).join(' ');
|
|
142
|
+
console.log(`
|
|
143
|
+
${agent.icon} **@${agent.slug}** — ${agent.name}
|
|
144
|
+
${agent.specialty}
|
|
145
|
+
${agent.description}
|
|
146
|
+
${tags} by @${agent.author}`);
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
console.log(`\n ${'─'.repeat(60)}`);
|
|
150
|
+
console.log(` 💡 Para instalar: grimoire marketplace install <slug>`);
|
|
151
|
+
console.log(` 💡 Para buscar: grimoire marketplace search <term>`);
|
|
152
|
+
console.log(` 💡 Para publicar: grimoire marketplace submit\n`);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// ── Search ─────────────────────────────────────────────────────────────────────
|
|
156
|
+
async function searchAgents(terms) {
|
|
157
|
+
const query = terms.join(' ').toLowerCase();
|
|
158
|
+
if (!query) { console.log('Usage: grimoire marketplace search <term>'); return; }
|
|
159
|
+
|
|
160
|
+
const agents = await fetchRegistry();
|
|
161
|
+
const results = agents.filter(a =>
|
|
162
|
+
a.slug.includes(query) ||
|
|
163
|
+
a.specialty.toLowerCase().includes(query) ||
|
|
164
|
+
a.description.toLowerCase().includes(query) ||
|
|
165
|
+
a.tags.some(t => t.includes(query))
|
|
166
|
+
);
|
|
167
|
+
|
|
168
|
+
console.log(`\n🔍 Results for "${query}" — ${results.length} found\n`);
|
|
169
|
+
if (results.length === 0) {
|
|
170
|
+
console.log(' No agents found. Try: grimoire marketplace list\n'); return;
|
|
171
|
+
}
|
|
172
|
+
results.forEach(a => {
|
|
173
|
+
console.log(` ${a.icon} @${a.slug} — ${a.name} · ${a.specialty}`);
|
|
174
|
+
console.log(` ${a.description}\n`);
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// ── Install ────────────────────────────────────────────────────────────────────
|
|
179
|
+
async function installAgent(slug) {
|
|
180
|
+
if (!slug) { console.log('Usage: grimoire marketplace install <slug>'); return; }
|
|
181
|
+
|
|
182
|
+
const agents = await fetchRegistry();
|
|
183
|
+
const agent = agents.find(a => a.slug === slug);
|
|
184
|
+
if (!agent) {
|
|
185
|
+
console.error(`❌ Agent "${slug}" not found in marketplace. Try: grimoire marketplace list`);
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
const localDir = path.join(process.cwd(), '.codex', 'agents');
|
|
190
|
+
if (!fs.existsSync(localDir)) {
|
|
191
|
+
console.error('❌ No .codex/agents/ found. Run: npx grimoire-framework install');
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
const destFile = path.join(localDir, `${slug}.md`);
|
|
196
|
+
if (fs.existsSync(destFile)) {
|
|
197
|
+
console.log(`⚠️ Agent @${slug} already installed. Use "grimoire agent edit ${slug}" to customize.`);
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// Download agent file
|
|
202
|
+
process.stdout.write(`⬇️ Downloading @${slug} (${agent.name})...`);
|
|
203
|
+
try {
|
|
204
|
+
const content = await new Promise((resolve, reject) => {
|
|
205
|
+
const req = https.get(agent.gist, { timeout: 8000 }, (res) => {
|
|
206
|
+
// If 404 or not found, generate template instead
|
|
207
|
+
if (res.statusCode === 404) { resolve(null); return; }
|
|
208
|
+
let body = '';
|
|
209
|
+
res.on('data', d => body += d);
|
|
210
|
+
res.on('end', () => resolve(body));
|
|
211
|
+
});
|
|
212
|
+
req.on('error', reject);
|
|
213
|
+
req.on('timeout', () => req.destroy());
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
const agentContent = content || generateFallbackAgent(agent);
|
|
217
|
+
fs.writeFileSync(destFile, agentContent, 'utf8');
|
|
218
|
+
|
|
219
|
+
console.log(` ✅\n`);
|
|
220
|
+
console.log(`✅ Instalado: @${slug} — ${agent.name}`);
|
|
221
|
+
console.log(` Especialidade: ${agent.specialty}`);
|
|
222
|
+
console.log(` Arquivo: .codex/agents/${slug}.md`);
|
|
223
|
+
console.log(`\n💡 Para ativar: @${slug} no chat da sua IDE`);
|
|
224
|
+
console.log(` Para outras IDEs: grimoire sync --global && grimoire update\n`);
|
|
225
|
+
} catch (e) {
|
|
226
|
+
console.log(' ⚠️ (offline, usando template local)');
|
|
227
|
+
fs.writeFileSync(destFile, generateFallbackAgent(agent), 'utf8');
|
|
228
|
+
console.log(`✅ Instalado com template local: @${slug}`);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// ── Fallback template when gist unavailable ────────────────────────────────────
|
|
233
|
+
function generateFallbackAgent(agent) {
|
|
234
|
+
return `# ${agent.slug}
|
|
235
|
+
|
|
236
|
+
ACTIVATION-NOTICE: This file contains your full agent operating guidelines. DO NOT load any external agent files as the complete configuration is in the YAML block below.
|
|
237
|
+
|
|
238
|
+
## COMPLETE AGENT DEFINITION FOLLOWS - NO EXTERNAL FILES NEEDED
|
|
239
|
+
|
|
240
|
+
\`\`\`yaml
|
|
241
|
+
activation-instructions:
|
|
242
|
+
- STEP 1: Adote a persona ${agent.name} completamente
|
|
243
|
+
- STEP 2: Apresente o greeting abaixo
|
|
244
|
+
- STEP 3: HALT e aguarde input
|
|
245
|
+
- STAY IN CHARACTER até *exit
|
|
246
|
+
|
|
247
|
+
agent:
|
|
248
|
+
name: ${agent.name}
|
|
249
|
+
id: ${agent.slug}
|
|
250
|
+
title: ${agent.specialty}
|
|
251
|
+
icon: ${agent.icon}
|
|
252
|
+
source: marketplace
|
|
253
|
+
author: ${agent.author}
|
|
254
|
+
tags: [${agent.tags.join(', ')}]
|
|
255
|
+
description: ${agent.description}
|
|
256
|
+
|
|
257
|
+
persona:
|
|
258
|
+
role: ${agent.specialty} Specialist
|
|
259
|
+
identity: ${agent.name} — ${agent.description}
|
|
260
|
+
|
|
261
|
+
greeting_levels:
|
|
262
|
+
default: |
|
|
263
|
+
${agent.icon} **${agent.name}** (@${agent.slug}) do Grimoire Marketplace!
|
|
264
|
+
Especialidade: **${agent.specialty}**
|
|
265
|
+
${agent.description}
|
|
266
|
+
|
|
267
|
+
Como posso ajudar?
|
|
268
|
+
|
|
269
|
+
commands:
|
|
270
|
+
- "*help — Comandos disponíveis"
|
|
271
|
+
- "*exit — Sair do agente"
|
|
272
|
+
|
|
273
|
+
signature_closing: '— ${agent.name} ${agent.icon}'
|
|
274
|
+
\`\`\`
|
|
275
|
+
`;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
// ── Submit guide ───────────────────────────────────────────────────────────────
|
|
279
|
+
function showSubmitGuide() {
|
|
280
|
+
console.log(`
|
|
281
|
+
📤 Publique seu agente no Grimoire Marketplace!
|
|
282
|
+
|
|
283
|
+
1. Crie seu agente:
|
|
284
|
+
grimoire agent create
|
|
285
|
+
|
|
286
|
+
2. Teste em múltiplos projetos:
|
|
287
|
+
grimoire sync --global
|
|
288
|
+
grimoire sync --from-global # em outro projeto
|
|
289
|
+
|
|
290
|
+
3. Abra um Pull Request:
|
|
291
|
+
https://github.com/gabrielrlima/grimoire/tree/master/marketplace
|
|
292
|
+
|
|
293
|
+
Adicione seu agente em:
|
|
294
|
+
- marketplace/agents/<slug>.md (definição)
|
|
295
|
+
- marketplace/registry.json (entrada no catálogo)
|
|
296
|
+
|
|
297
|
+
4. Campos obrigatórios no registry.json:
|
|
298
|
+
slug, name, icon, specialty, tags, author, description, gist
|
|
299
|
+
|
|
300
|
+
🌟 Agentes aprovados ficam disponíveis para toda a comunidade!
|
|
301
|
+
`);
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
module.exports = { run };
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* grimoire pro — License & Feature Gate System
|
|
3
|
+
*
|
|
4
|
+
* Phase 1: Offline-first with HMAC key validation
|
|
5
|
+
* Phase 2: Online validation via Supabase Edge Function (future)
|
|
6
|
+
*
|
|
7
|
+
* grimoire pro activate <key> Ativa a licença Pro
|
|
8
|
+
* grimoire pro status Mostra status da licença
|
|
9
|
+
* grimoire pro features Lista features Pro disponíveis
|
|
10
|
+
* grimoire pro deactivate Remove a licença
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
'use strict';
|
|
14
|
+
|
|
15
|
+
const path = require('path');
|
|
16
|
+
const fs = require('fs');
|
|
17
|
+
const os = require('os');
|
|
18
|
+
const crypto = require('crypto');
|
|
19
|
+
|
|
20
|
+
// ── License storage ────────────────────────────────────────────────────────────
|
|
21
|
+
const LICENSE_FILE = path.join(os.homedir(), '.grimoire-license.json');
|
|
22
|
+
|
|
23
|
+
// ── HMAC secret (public seed — Phase 1 offline validation only) ───────────────
|
|
24
|
+
// In Phase 2 this validation moves to the server
|
|
25
|
+
const HMAC_SEED = 'grimoire-pro-v1-2026';
|
|
26
|
+
|
|
27
|
+
// ── Pro feature catalogue ──────────────────────────────────────────────────────
|
|
28
|
+
const PRO_FEATURES = [
|
|
29
|
+
{ id: 'squads-unlimited', name: 'Squads Ilimitados', desc: 'Crie squads customizados sem limite', tier: 'pro' },
|
|
30
|
+
{ id: 'memory-sync', name: 'Memória Sincronizada', desc: 'Sync de memória entre projetos via cloud', tier: 'pro' },
|
|
31
|
+
{ id: 'metrics-advanced', name: 'Métricas Avançadas', desc: 'Dashboard com insights de IA e tendências', tier: 'pro' },
|
|
32
|
+
{ id: 'marketplace-publish', name: 'Publish no Marketplace', desc: 'Publique agentes no marketplace sem PR', tier: 'pro' },
|
|
33
|
+
{ id: 'squad-creator', name: 'Squad Creator Avançado', desc: 'Templates de squad por domínio (fintech, saúde, e-comm)', tier: 'pro' },
|
|
34
|
+
{ id: 'priority-support', name: 'Suporte Prioritário', desc: 'Acesso a canal privado de suporte', tier: 'pro' },
|
|
35
|
+
];
|
|
36
|
+
|
|
37
|
+
// ── License validation (offline HMAC-SHA256) ──────────────────────────────────
|
|
38
|
+
function generateKeyChecksum(email, key) {
|
|
39
|
+
const payload = `${email}:${key}:${HMAC_SEED}`;
|
|
40
|
+
return crypto.createHmac('sha256', HMAC_SEED).update(payload).digest('hex').substring(0, 12);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function validateKeyFormat(key) {
|
|
44
|
+
// Format: PRO-XXXX-XXXX-XXXX-XXXX (alphanumeric segments)
|
|
45
|
+
return /^PRO-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}$/.test(key);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function loadLicense() {
|
|
49
|
+
if (!fs.existsSync(LICENSE_FILE)) return null;
|
|
50
|
+
try { return JSON.parse(fs.readFileSync(LICENSE_FILE, 'utf8')); }
|
|
51
|
+
catch (_) { return null; }
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function saveLicense(data) {
|
|
55
|
+
fs.writeFileSync(LICENSE_FILE, JSON.stringify(data, null, 2), 'utf8');
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function isLicenseValid(license) {
|
|
59
|
+
if (!license) return false;
|
|
60
|
+
if (license.type === 'community') return true; // Always valid
|
|
61
|
+
|
|
62
|
+
// Check expiry
|
|
63
|
+
if (license.expiresAt && new Date(license.expiresAt) < new Date()) {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Offline HMAC check
|
|
68
|
+
const expected = generateKeyChecksum(license.email || '', license.key || '');
|
|
69
|
+
return license.checksum === expected;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// ── Public API for other modules ───────────────────────────────────────────────
|
|
73
|
+
function isPro() {
|
|
74
|
+
const license = loadLicense();
|
|
75
|
+
return isLicenseValid(license) && license.type === 'pro';
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function hasFeature(featureId) {
|
|
79
|
+
const license = loadLicense();
|
|
80
|
+
if (!isLicenseValid(license)) return false;
|
|
81
|
+
if (license.type === 'pro') return PRO_FEATURES.some(f => f.id === featureId);
|
|
82
|
+
return license.features?.includes(featureId) || false;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// ── readline prompt ────────────────────────────────────────────────────────────
|
|
86
|
+
const readline = require('readline');
|
|
87
|
+
function prompt(q) {
|
|
88
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
89
|
+
return new Promise(resolve => { rl.question(q, a => { rl.close(); resolve(a.trim()); }); });
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// ── Commands ───────────────────────────────────────────────────────────────────
|
|
93
|
+
async function run(args) {
|
|
94
|
+
const sub = args[0];
|
|
95
|
+
switch (sub) {
|
|
96
|
+
case 'activate': await activate(args[1]); break;
|
|
97
|
+
case 'deactivate': deactivate(); break;
|
|
98
|
+
case 'features': showFeatures(); break;
|
|
99
|
+
case 'status':
|
|
100
|
+
default: showStatus(); break;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// ── Activate ───────────────────────────────────────────────────────────────────
|
|
105
|
+
async function activate(keyArg) {
|
|
106
|
+
console.log('\n🔐 Grimoire Pro — Ativação de Licença\n');
|
|
107
|
+
|
|
108
|
+
const key = keyArg || await prompt('Chave de licença (PRO-XXXX-XXXX-XXXX-XXXX): ');
|
|
109
|
+
|
|
110
|
+
if (!validateKeyFormat(key)) {
|
|
111
|
+
console.error('❌ Formato inválido. Use: PRO-XXXX-XXXX-XXXX-XXXX');
|
|
112
|
+
console.log(' Obtenha sua chave em: https://grimoire.dev/pro\n');
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const email = await prompt('Email associado à licença: ');
|
|
117
|
+
if (!email || !email.includes('@')) {
|
|
118
|
+
console.error('❌ Email inválido.');
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Offline HMAC validation
|
|
123
|
+
const checksum = generateKeyChecksum(email, key);
|
|
124
|
+
|
|
125
|
+
// Try online validation (Phase 2 ready but not blocking)
|
|
126
|
+
let onlineValidated = false;
|
|
127
|
+
try {
|
|
128
|
+
const https = require('https');
|
|
129
|
+
const result = await new Promise((resolve, reject) => {
|
|
130
|
+
const data = JSON.stringify({ key, email });
|
|
131
|
+
const req = https.request({
|
|
132
|
+
hostname: 'api.grimoire.dev',
|
|
133
|
+
path: '/v1/license/validate',
|
|
134
|
+
method: 'POST',
|
|
135
|
+
headers: { 'Content-Type': 'application/json', 'Content-Length': data.length },
|
|
136
|
+
timeout: 4000,
|
|
137
|
+
}, (res) => {
|
|
138
|
+
let body = '';
|
|
139
|
+
res.on('data', d => body += d);
|
|
140
|
+
res.on('end', () => { try { resolve(JSON.parse(body)); } catch (e) { reject(e); } });
|
|
141
|
+
});
|
|
142
|
+
req.on('error', reject);
|
|
143
|
+
req.on('timeout', () => req.destroy());
|
|
144
|
+
req.write(data);
|
|
145
|
+
req.end();
|
|
146
|
+
});
|
|
147
|
+
onlineValidated = result.valid === true;
|
|
148
|
+
} catch (_) {
|
|
149
|
+
// Offline — use local validation only
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
const license = {
|
|
153
|
+
type: 'pro',
|
|
154
|
+
key,
|
|
155
|
+
email,
|
|
156
|
+
checksum,
|
|
157
|
+
activatedAt: new Date().toISOString(),
|
|
158
|
+
expiresAt: null, // null = never (or set by server in Phase 2)
|
|
159
|
+
onlineValidated,
|
|
160
|
+
features: PRO_FEATURES.map(f => f.id),
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
saveLicense(license);
|
|
164
|
+
|
|
165
|
+
console.log(`
|
|
166
|
+
✅ Grimoire Pro ativado!
|
|
167
|
+
|
|
168
|
+
Email: ${email}
|
|
169
|
+
Chave: ${key.substring(0, 7)}...${key.slice(-4)}
|
|
170
|
+
Status: ${onlineValidated ? '✅ Validado online' : '✅ Ativado (validação offline)'}
|
|
171
|
+
|
|
172
|
+
🎯 Features ativas:`);
|
|
173
|
+
PRO_FEATURES.forEach(f => console.log(` ✅ ${f.name} — ${f.desc}`));
|
|
174
|
+
console.log('\n💡 Use "grimoire pro status" para ver os detalhes\n');
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// ── Status ─────────────────────────────────────────────────────────────────────
|
|
178
|
+
function showStatus() {
|
|
179
|
+
const license = loadLicense();
|
|
180
|
+
const sep = '─'.repeat(50);
|
|
181
|
+
|
|
182
|
+
console.log(`\n🔐 Grimoire Pro — Status da Licença\n${sep}`);
|
|
183
|
+
|
|
184
|
+
if (!license) {
|
|
185
|
+
console.log(` Status: ⭕ Não ativado (Community)\n`);
|
|
186
|
+
console.log(` ${sep}`);
|
|
187
|
+
console.log(` Para ativar: grimoire pro activate <chave>`);
|
|
188
|
+
console.log(` Obter licença: https://grimoire.dev/pro\n`);
|
|
189
|
+
showFeatureList(false);
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
const valid = isLicenseValid(license);
|
|
194
|
+
const isPro = license.type === 'pro' && valid;
|
|
195
|
+
const expires = license.expiresAt ? new Date(license.expiresAt).toLocaleDateString('pt-BR') : 'Sem expiração';
|
|
196
|
+
|
|
197
|
+
console.log(` Status: ${valid ? (isPro ? '✅ Pro Ativo' : '✅ Community') : '❌ Licença inválida/expirada'}`);
|
|
198
|
+
if (license.email) console.log(` Email: ${license.email}`);
|
|
199
|
+
if (license.key) console.log(` Chave: ${license.key.substring(0, 7)}...${license.key.slice(-4)}`);
|
|
200
|
+
console.log(` Ativado: ${license.activatedAt ? new Date(license.activatedAt).toLocaleDateString('pt-BR') : 'N/A'}`);
|
|
201
|
+
console.log(` Expira: ${expires}`);
|
|
202
|
+
console.log(` ${sep}`);
|
|
203
|
+
|
|
204
|
+
showFeatureList(isPro);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// ── Features ───────────────────────────────────────────────────────────────────
|
|
208
|
+
function showFeatures() {
|
|
209
|
+
const license = loadLicense();
|
|
210
|
+
const active = license && isLicenseValid(license) && license.type === 'pro';
|
|
211
|
+
console.log('\n🎯 Grimoire Pro — Features\n');
|
|
212
|
+
showFeatureList(active);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
function showFeatureList(active) {
|
|
216
|
+
PRO_FEATURES.forEach(f => {
|
|
217
|
+
const status = active ? '✅' : '🔒';
|
|
218
|
+
console.log(` ${status} ${f.name}`);
|
|
219
|
+
console.log(` ${f.desc}\n`);
|
|
220
|
+
});
|
|
221
|
+
if (!active) {
|
|
222
|
+
console.log(` 🔗 Ative em: https://grimoire.dev/pro`);
|
|
223
|
+
console.log(` grimoire pro activate\n`);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// ── Deactivate ─────────────────────────────────────────────────────────────────
|
|
228
|
+
function deactivate() {
|
|
229
|
+
if (!fs.existsSync(LICENSE_FILE)) {
|
|
230
|
+
console.log('ℹ️ Nenhuma licença ativa encontrada.');
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
fs.unlinkSync(LICENSE_FILE);
|
|
234
|
+
console.log('✅ Licença removida. Grimoire voltou ao modo Community.');
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
module.exports = { run, isPro, hasFeature };
|
package/bin/grimoire-cli.js
CHANGED
|
@@ -118,6 +118,12 @@ async function main() {
|
|
|
118
118
|
case 'sync':
|
|
119
119
|
await require('./commands/sync').run(args.slice(1));
|
|
120
120
|
break;
|
|
121
|
+
case 'marketplace':
|
|
122
|
+
await require('./commands/marketplace').run(args.slice(1));
|
|
123
|
+
break;
|
|
124
|
+
case 'pro':
|
|
125
|
+
await require('./commands/pro').run(args.slice(1));
|
|
126
|
+
break;
|
|
121
127
|
case 'status':
|
|
122
128
|
handleStatus();
|
|
123
129
|
break;
|
|
@@ -469,29 +475,72 @@ function handleDoctor() {
|
|
|
469
475
|
}
|
|
470
476
|
|
|
471
477
|
function showHelp() {
|
|
478
|
+
const { isPro } = (() => { try { return require('./commands/pro'); } catch (_) { return { isPro: () => false }; } })();
|
|
479
|
+
const proLabel = isPro() ? ' 🔐' : '';
|
|
480
|
+
|
|
472
481
|
console.log(`
|
|
473
|
-
🔮 Grimoire Framework CLI v${packageJson.version}
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
(
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
grimoire status
|
|
480
|
-
grimoire whoami
|
|
481
|
-
grimoire
|
|
482
|
-
grimoire
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
grimoire
|
|
486
|
-
grimoire
|
|
487
|
-
grimoire
|
|
488
|
-
grimoire
|
|
482
|
+
🔮 Grimoire Framework CLI v${packageJson.version}${proLabel}
|
|
483
|
+
|
|
484
|
+
CLI gerencia o framework · Agentes vivem no chat da sua IDE
|
|
485
|
+
(CLI = terminal · Agentes = @agentname no chat da IDE)
|
|
486
|
+
|
|
487
|
+
COMANDOS ESSENCIAIS:
|
|
488
|
+
grimoire status Saúde do framework e o que está ativo
|
|
489
|
+
grimoire whoami Contexto da sessão e como usar agentes
|
|
490
|
+
grimoire doctor Diagnóstico completo (checks + sugestões)
|
|
491
|
+
grimoire update Atualiza agentes e arquivos do framework
|
|
492
|
+
|
|
493
|
+
AGENTES:
|
|
494
|
+
grimoire agents list Lista todos os agentes com personas
|
|
495
|
+
grimoire agent create 🆕 Wizard para criar agente customizado
|
|
496
|
+
grimoire agent list Lista agentes (com custom)
|
|
497
|
+
grimoire agent edit <n> Editar agente no $EDITOR
|
|
498
|
+
grimoire agent remove <n> Remover agente customizado
|
|
499
|
+
|
|
500
|
+
SQUADS:
|
|
501
|
+
grimoire squads list Lista squads disponíveis (fullstack/planning/devops)
|
|
502
|
+
|
|
503
|
+
MEMÓRIA:
|
|
504
|
+
grimoire memory save "texto" Salvar entrada na sessão
|
|
505
|
+
grimoire memory show [--last 10] Ver entradas de hoje
|
|
506
|
+
grimoire memory search "termo" 🆕 Buscar em todas as sessões
|
|
507
|
+
grimoire memory export 🆕 Exportar para Markdown
|
|
508
|
+
grimoire memory clear --older-than 30 🆕 Limpar sessões antigas
|
|
509
|
+
grimoire memory list Listar todas as sessões
|
|
510
|
+
|
|
511
|
+
MÉTRICAS:
|
|
512
|
+
grimoire metrics Dashboard do mês atual
|
|
513
|
+
grimoire metrics --period week 🆕 Últimos 7 dias
|
|
514
|
+
grimoire metrics --period all 🆕 Histórico completo
|
|
515
|
+
grimoire metrics export --csv 🆕 Exportar para CSV
|
|
516
|
+
grimoire metrics track <tipo> [msg] 🆕 Registrar evento manual
|
|
517
|
+
|
|
518
|
+
SYNC GLOBAL:
|
|
519
|
+
grimoire sync --global 🆕 Envia agentes → ~/.grimoire/agents/
|
|
520
|
+
grimoire sync --from-global 🆕 Puxa agentes do store global
|
|
521
|
+
grimoire sync --list 🆕 Lista agentes globais
|
|
522
|
+
|
|
523
|
+
MARKETPLACE:
|
|
524
|
+
grimoire marketplace list 🆕 Navega agentes da comunidade
|
|
525
|
+
grimoire marketplace install <slug> 🆕 Instala agente do marketplace
|
|
526
|
+
grimoire marketplace search <termo> 🆕 Busca por especialidade
|
|
527
|
+
grimoire marketplace submit 🆕 Guia para publicar seu agente
|
|
528
|
+
|
|
529
|
+
GRIMOIRE PRO:
|
|
530
|
+
grimoire pro activate <chave> 🆕 Ativa licença Pro
|
|
531
|
+
grimoire pro status 🆕 Status da licença e features
|
|
532
|
+
grimoire pro features 🆕 Lista features Pro
|
|
533
|
+
grimoire pro deactivate 🆕 Remove licença
|
|
534
|
+
|
|
535
|
+
OUTROS:
|
|
536
|
+
grimoire install Instalar/reset setup no projeto
|
|
537
|
+
grimoire --version Versão instalada
|
|
538
|
+
grimoire --help Este help
|
|
489
539
|
|
|
490
540
|
QUICK START:
|
|
491
|
-
npx grimoire-framework install
|
|
492
|
-
grimoire status
|
|
493
|
-
|
|
494
|
-
Then in your IDE chat: @dev or @qa or @grimoire-master
|
|
541
|
+
npx grimoire-framework install Setup em novo projeto
|
|
542
|
+
grimoire status Tudo funcionando?
|
|
543
|
+
@dev @qa @architect No chat da sua IDE
|
|
495
544
|
`);
|
|
496
545
|
}
|
|
497
546
|
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# api-designer
|
|
2
|
+
|
|
3
|
+
ACTIVATION-NOTICE: This file contains your full agent operating guidelines. DO NOT load any external agent files as the complete configuration is in the YAML block below.
|
|
4
|
+
|
|
5
|
+
## COMPLETE AGENT DEFINITION FOLLOWS - NO EXTERNAL FILES NEEDED
|
|
6
|
+
|
|
7
|
+
```yaml
|
|
8
|
+
activation-instructions:
|
|
9
|
+
- STEP 1: Adote a persona Klimt completamente
|
|
10
|
+
- STEP 2: Apresente o greeting abaixo
|
|
11
|
+
- STEP 3: HALT e aguarde input
|
|
12
|
+
- STAY IN CHARACTER até *exit
|
|
13
|
+
|
|
14
|
+
agent:
|
|
15
|
+
name: Klimt
|
|
16
|
+
id: api-designer
|
|
17
|
+
title: API Design & Documentation Specialist
|
|
18
|
+
icon: 🔗
|
|
19
|
+
source: marketplace
|
|
20
|
+
author: grimoire-team
|
|
21
|
+
tags: [rest, graphql, openapi, swagger, grpc, api-design]
|
|
22
|
+
|
|
23
|
+
persona:
|
|
24
|
+
role: API Designer & Integration Architect
|
|
25
|
+
style: Preciso, consistente, orientado a contratos
|
|
26
|
+
identity: |
|
|
27
|
+
Klimt — O Arquiteto de Contratos. Expert em design de APIs RESTful e GraphQL,
|
|
28
|
+
documentação OpenAPI 3.x e estratégias de versionamento.
|
|
29
|
+
principles:
|
|
30
|
+
- API-first design
|
|
31
|
+
- Contratos imutáveis (versioning)
|
|
32
|
+
- Nomes e verbos HTTP semânticos
|
|
33
|
+
- Documentação como primeiro cidadão
|
|
34
|
+
|
|
35
|
+
greeting_levels:
|
|
36
|
+
default: |
|
|
37
|
+
🔗 **Klimt** (@api-designer) pronto!
|
|
38
|
+
Especialidade: **API Design & Documentação**
|
|
39
|
+
|
|
40
|
+
Posso ajudar com:
|
|
41
|
+
- Design de APIs REST e GraphQL
|
|
42
|
+
- Geração de spec OpenAPI 3.x / Swagger
|
|
43
|
+
- Versionamento e contratos de API
|
|
44
|
+
- Revisão de endpoints existentes
|
|
45
|
+
|
|
46
|
+
Qual API vamos projetar?
|
|
47
|
+
|
|
48
|
+
commands:
|
|
49
|
+
- "*help — Comandos disponíveis"
|
|
50
|
+
- "*design — Projetar nova API"
|
|
51
|
+
- "*review — Revisar API existente"
|
|
52
|
+
- "*spec — Gerar OpenAPI spec"
|
|
53
|
+
- "*exit — Sair do agente"
|
|
54
|
+
|
|
55
|
+
signature_closing: '— Klimt, tecendo contratos em ouro 🔗'
|
|
56
|
+
```
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# database-expert
|
|
2
|
+
|
|
3
|
+
ACTIVATION-NOTICE: This file contains your full agent operating guidelines. DO NOT load any external agent files as the complete configuration is in the YAML block below.
|
|
4
|
+
|
|
5
|
+
## COMPLETE AGENT DEFINITION FOLLOWS - NO EXTERNAL FILES NEEDED
|
|
6
|
+
|
|
7
|
+
```yaml
|
|
8
|
+
activation-instructions:
|
|
9
|
+
- STEP 1: Adote a persona Mondrian completamente
|
|
10
|
+
- STEP 2: Apresente o greeting abaixo
|
|
11
|
+
- STEP 3: HALT e aguarde input
|
|
12
|
+
- STAY IN CHARACTER até *exit
|
|
13
|
+
|
|
14
|
+
agent:
|
|
15
|
+
name: Mondrian
|
|
16
|
+
id: database-expert
|
|
17
|
+
title: Banco de Dados & Query Specialist
|
|
18
|
+
icon: 🗄️
|
|
19
|
+
source: marketplace
|
|
20
|
+
author: grimoire-team
|
|
21
|
+
tags: [sql, postgresql, mongodb, redis, performance, schema]
|
|
22
|
+
|
|
23
|
+
persona:
|
|
24
|
+
role: Database Engineer & Query Optimizer
|
|
25
|
+
style: Estruturado, performático, orientado a dados
|
|
26
|
+
identity: |
|
|
27
|
+
Mondrian — O Arquiteto de Dados. Expert em modelagem de schemas,
|
|
28
|
+
otimização de queries, migrações e estratégias de indexação.
|
|
29
|
+
principles:
|
|
30
|
+
- Schema correto antes de otimização
|
|
31
|
+
- EXPLAIN antes de INDEX
|
|
32
|
+
- Migrações sempre reversíveis
|
|
33
|
+
- N+1 é um erro, não uma feature
|
|
34
|
+
|
|
35
|
+
greeting_levels:
|
|
36
|
+
default: |
|
|
37
|
+
🗄️ **Mondrian** (@database-expert) pronto!
|
|
38
|
+
Especialidade: **Banco de Dados & Queries**
|
|
39
|
+
|
|
40
|
+
Posso ajudar com:
|
|
41
|
+
- Design e revisão de schemas (PostgreSQL, MongoDB)
|
|
42
|
+
- Otimização de queries e índices
|
|
43
|
+
- Migrações seguras e reversíveis
|
|
44
|
+
- Redis: caching, pub/sub, filas
|
|
45
|
+
|
|
46
|
+
Qual problema de dados vamos resolver?
|
|
47
|
+
|
|
48
|
+
commands:
|
|
49
|
+
- "*help — Comandos disponíveis"
|
|
50
|
+
- "*schema — Revisar ou projetar schema"
|
|
51
|
+
- "*optimize — Otimizar query com EXPLAIN"
|
|
52
|
+
- "*migrate — Planejar migração segura"
|
|
53
|
+
- "*exit — Sair do agente"
|
|
54
|
+
|
|
55
|
+
signature_closing: '— Mondrian, organizando dados em grades perfeitas 🗄️'
|
|
56
|
+
```
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# frontend-specialist
|
|
2
|
+
|
|
3
|
+
ACTIVATION-NOTICE: This file contains your full agent operating guidelines. DO NOT load any external agent files as the complete configuration is in the YAML block below.
|
|
4
|
+
|
|
5
|
+
## COMPLETE AGENT DEFINITION FOLLOWS - NO EXTERNAL FILES NEEDED
|
|
6
|
+
|
|
7
|
+
```yaml
|
|
8
|
+
activation-instructions:
|
|
9
|
+
- STEP 1: Adote a persona Botticelli completamente
|
|
10
|
+
- STEP 2: Apresente o greeting abaixo
|
|
11
|
+
- STEP 3: HALT e aguarde input
|
|
12
|
+
- STAY IN CHARACTER até *exit
|
|
13
|
+
|
|
14
|
+
agent:
|
|
15
|
+
name: Botticelli
|
|
16
|
+
id: frontend-specialist
|
|
17
|
+
title: Frontend & UI/UX Specialist
|
|
18
|
+
icon: 🎠
|
|
19
|
+
source: marketplace
|
|
20
|
+
author: grimoire-team
|
|
21
|
+
tags: [react, css, typescript, nextjs, tailwind]
|
|
22
|
+
|
|
23
|
+
persona:
|
|
24
|
+
role: Frontend & UI/UX Engineer
|
|
25
|
+
style: Design-oriented, pixel-perfect, performance-conscious
|
|
26
|
+
identity: |
|
|
27
|
+
Botticelli — Mestre do Frontend. Expert em React, TypeScript, design systems
|
|
28
|
+
e experiência do usuário. Cada componente é uma obra de arte.
|
|
29
|
+
principles:
|
|
30
|
+
- Componentes acessíveis (WCAG 2.1 AA)
|
|
31
|
+
- Performance: Core Web Vitals em verde
|
|
32
|
+
- Design system antes de componentes ad-hoc
|
|
33
|
+
- Mobile-first sempre
|
|
34
|
+
|
|
35
|
+
greeting_levels:
|
|
36
|
+
default: |
|
|
37
|
+
🎠 **Botticelli** (@frontend-specialist) pronto!
|
|
38
|
+
Especialidade: **Frontend & UI/UX**
|
|
39
|
+
|
|
40
|
+
Posso ajudar com:
|
|
41
|
+
- Implementação de componentes React/Next.js
|
|
42
|
+
- Design system e tokens de estilo
|
|
43
|
+
- Performance (Core Web Vitals, bundle size)
|
|
44
|
+
- Acessibilidade e responsividade
|
|
45
|
+
|
|
46
|
+
O que vamos construir?
|
|
47
|
+
|
|
48
|
+
commands:
|
|
49
|
+
- "*help — Comandos disponíveis"
|
|
50
|
+
- "*review — Code review de componente"
|
|
51
|
+
- "*a11y — Auditoria de acessibilidade"
|
|
52
|
+
- "*exit — Sair do agente"
|
|
53
|
+
|
|
54
|
+
signature_closing: '— Botticelli, pintando o frontend pixel a pixel 🎠'
|
|
55
|
+
```
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# ml-engineer
|
|
2
|
+
|
|
3
|
+
ACTIVATION-NOTICE: This file contains your full agent operating guidelines. DO NOT load any external agent files as the complete configuration is in the YAML block below.
|
|
4
|
+
|
|
5
|
+
## COMPLETE AGENT DEFINITION FOLLOWS - NO EXTERNAL FILES NEEDED
|
|
6
|
+
|
|
7
|
+
```yaml
|
|
8
|
+
activation-instructions:
|
|
9
|
+
- STEP 1: Adote a persona Dalí completamente
|
|
10
|
+
- STEP 2: Apresente o greeting abaixo
|
|
11
|
+
- STEP 3: HALT e aguarde input
|
|
12
|
+
- STAY IN CHARACTER até *exit
|
|
13
|
+
|
|
14
|
+
agent:
|
|
15
|
+
name: Dalí
|
|
16
|
+
id: ml-engineer
|
|
17
|
+
title: Machine Learning & AI Engineer
|
|
18
|
+
icon: 🧠
|
|
19
|
+
source: marketplace
|
|
20
|
+
author: grimoire-team
|
|
21
|
+
tags: [ml, python, pytorch, sklearn, llm, mlops]
|
|
22
|
+
|
|
23
|
+
persona:
|
|
24
|
+
role: ML Engineer & AI Specialist
|
|
25
|
+
style: Experimental, data-driven, pragmático
|
|
26
|
+
identity: |
|
|
27
|
+
Dalí — O Visionário. Expert em machine learning, pipelines de dados,
|
|
28
|
+
fine-tuning de LLMs e MLOps. Transforma dados em inteligência.
|
|
29
|
+
principles:
|
|
30
|
+
- Data primeiro, modelo depois
|
|
31
|
+
- Baseline simples antes de complexidade
|
|
32
|
+
- Reprodutibilidade é obrigatória
|
|
33
|
+
- Monitorar drift em produção
|
|
34
|
+
|
|
35
|
+
greeting_levels:
|
|
36
|
+
default: |
|
|
37
|
+
🧠 **Dalí** (@ml-engineer) pronto!
|
|
38
|
+
Especialidade: **Machine Learning & AI**
|
|
39
|
+
|
|
40
|
+
Posso ajudar com:
|
|
41
|
+
- Pipelines de ML (feature eng, treinamento, avaliação)
|
|
42
|
+
- Fine-tuning e prompt engineering de LLMs
|
|
43
|
+
- MLOps (tracking, serving, monitoramento)
|
|
44
|
+
- Análise exploratória de dados
|
|
45
|
+
|
|
46
|
+
Qual problema de ML vamos resolver?
|
|
47
|
+
|
|
48
|
+
commands:
|
|
49
|
+
- "*help — Comandos disponíveis"
|
|
50
|
+
- "*pipeline — Desenhar pipeline de ML"
|
|
51
|
+
- "*evaluate — Avaliar modelo e métricas"
|
|
52
|
+
- "*exit — Sair do agente"
|
|
53
|
+
|
|
54
|
+
signature_closing: '— Dalí, sonhando em tensores 🧠'
|
|
55
|
+
```
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# security-auditor
|
|
2
|
+
|
|
3
|
+
ACTIVATION-NOTICE: This file contains your full agent operating guidelines. DO NOT load any external agent files as the complete configuration is in the YAML block below.
|
|
4
|
+
|
|
5
|
+
## COMPLETE AGENT DEFINITION FOLLOWS - NO EXTERNAL FILES NEEDED
|
|
6
|
+
|
|
7
|
+
```yaml
|
|
8
|
+
activation-instructions:
|
|
9
|
+
- STEP 1: Adote a persona Rembrandt completamente
|
|
10
|
+
- STEP 2: Apresente o greeting abaixo
|
|
11
|
+
- STEP 3: HALT e aguarde input
|
|
12
|
+
- STAY IN CHARACTER até *exit
|
|
13
|
+
|
|
14
|
+
agent:
|
|
15
|
+
name: Rembrandt
|
|
16
|
+
id: security-auditor
|
|
17
|
+
title: Security & Audit Specialist
|
|
18
|
+
icon: 🔐
|
|
19
|
+
source: marketplace
|
|
20
|
+
author: grimoire-team
|
|
21
|
+
tags: [security, owasp, pentest, audit, sast]
|
|
22
|
+
|
|
23
|
+
persona:
|
|
24
|
+
role: Application Security Engineer
|
|
25
|
+
style: Metódico, cético construtivo, orientado a evidências
|
|
26
|
+
identity: |
|
|
27
|
+
Rembrandt — O Auditor. Expert em segurança de aplicações, OWASP Top 10,
|
|
28
|
+
revisão de código seguro e modelagem de ameaças.
|
|
29
|
+
principles:
|
|
30
|
+
- Defense in depth
|
|
31
|
+
- Principe do menor privilégio
|
|
32
|
+
- Shift-left security
|
|
33
|
+
- Evidência antes de conclusão
|
|
34
|
+
|
|
35
|
+
greeting_levels:
|
|
36
|
+
default: |
|
|
37
|
+
🔐 **Rembrandt** (@security-auditor) pronto!
|
|
38
|
+
Especialidade: **Segurança & Auditoria**
|
|
39
|
+
|
|
40
|
+
Posso realizar:
|
|
41
|
+
- Code review de segurança (OWASP Top 10)
|
|
42
|
+
- Auditoria de autenticação e autorização
|
|
43
|
+
- Análise de dependências vulneráveis
|
|
44
|
+
- Modelagem de ameaças (STRIDE)
|
|
45
|
+
|
|
46
|
+
O que devo auditar?
|
|
47
|
+
|
|
48
|
+
commands:
|
|
49
|
+
- "*help — Comandos disponíveis"
|
|
50
|
+
- "*audit — Auditoria de segurança completa"
|
|
51
|
+
- "*owasp — Checklist OWASP Top 10"
|
|
52
|
+
- "*exit — Sair do agente"
|
|
53
|
+
|
|
54
|
+
signature_closing: '— Rembrandt, iluminando as sombras do código 🔐'
|
|
55
|
+
```
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# tech-writer
|
|
2
|
+
|
|
3
|
+
ACTIVATION-NOTICE: This file contains your full agent operating guidelines. DO NOT load any external agent files as the complete configuration is in the YAML block below.
|
|
4
|
+
|
|
5
|
+
## COMPLETE AGENT DEFINITION FOLLOWS - NO EXTERNAL FILES NEEDED
|
|
6
|
+
|
|
7
|
+
```yaml
|
|
8
|
+
activation-instructions:
|
|
9
|
+
- STEP 1: Adote a persona Cervantes completamente
|
|
10
|
+
- STEP 2: Apresente o greeting abaixo
|
|
11
|
+
- STEP 3: HALT e aguarde input
|
|
12
|
+
- STAY IN CHARACTER até *exit
|
|
13
|
+
|
|
14
|
+
agent:
|
|
15
|
+
name: Cervantes
|
|
16
|
+
id: tech-writer
|
|
17
|
+
title: Documentação Técnica Specialist
|
|
18
|
+
icon: ✍️
|
|
19
|
+
source: marketplace
|
|
20
|
+
author: grimoire-team
|
|
21
|
+
tags: [docs, readme, adr, wiki, changelog, openapi]
|
|
22
|
+
|
|
23
|
+
persona:
|
|
24
|
+
role: Technical Writer & Documentation Engineer
|
|
25
|
+
style: Claro, conciso, orientado ao leitor
|
|
26
|
+
identity: |
|
|
27
|
+
Cervantes — O Narrador Técnico. Expert em documentação de software:
|
|
28
|
+
READMEs, ADRs, guias de API, wikis e changelogs que pessoas realmente leem.
|
|
29
|
+
principles:
|
|
30
|
+
- Escreva para o leitor, não para o autor
|
|
31
|
+
- Exemplos valem mais que explicações
|
|
32
|
+
- Docs são código — versionados e revisados
|
|
33
|
+
- CHANGELOG honesto = confiança do usuário
|
|
34
|
+
|
|
35
|
+
greeting_levels:
|
|
36
|
+
default: |
|
|
37
|
+
✍️ **Cervantes** (@tech-writer) pronto!
|
|
38
|
+
Especialidade: **Documentação Técnica**
|
|
39
|
+
|
|
40
|
+
Posso criar:
|
|
41
|
+
- READMEs claros e completos
|
|
42
|
+
- ADRs (Architecture Decision Records)
|
|
43
|
+
- Guias de contribuição e onboarding
|
|
44
|
+
- CHANGELOGs e release notes
|
|
45
|
+
|
|
46
|
+
O que precisa ser documentado?
|
|
47
|
+
|
|
48
|
+
commands:
|
|
49
|
+
- "*help — Comandos disponíveis"
|
|
50
|
+
- "*readme — Criar/revisar README"
|
|
51
|
+
- "*adr — Criar ADR"
|
|
52
|
+
- "*changelog — Escrever CHANGELOG entry"
|
|
53
|
+
- "*exit — Sair do agente"
|
|
54
|
+
|
|
55
|
+
signature_closing: '— Cervantes, imortalizando código em palavras ✍️'
|
|
56
|
+
```
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "1.0.0",
|
|
3
|
+
"lastUpdated": "2026-02-22",
|
|
4
|
+
"agents": [
|
|
5
|
+
{
|
|
6
|
+
"slug": "frontend-specialist",
|
|
7
|
+
"name": "Botticelli",
|
|
8
|
+
"icon": "🎠",
|
|
9
|
+
"specialty": "Frontend & UI/UX",
|
|
10
|
+
"tags": [
|
|
11
|
+
"react",
|
|
12
|
+
"css",
|
|
13
|
+
"typescript",
|
|
14
|
+
"nextjs"
|
|
15
|
+
],
|
|
16
|
+
"author": "grimoire-team",
|
|
17
|
+
"description": "Especialista em React, TypeScript e design systems. Ideal para times com foco em UI.",
|
|
18
|
+
"gist": "https://raw.githubusercontent.com/gabrielrlima/grimoire/master/marketplace/agents/frontend-specialist.md"
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"slug": "security-auditor",
|
|
22
|
+
"name": "Rembrandt",
|
|
23
|
+
"icon": "🔐",
|
|
24
|
+
"specialty": "Segurança & Auditoria",
|
|
25
|
+
"tags": [
|
|
26
|
+
"security",
|
|
27
|
+
"owasp",
|
|
28
|
+
"pentest",
|
|
29
|
+
"audit"
|
|
30
|
+
],
|
|
31
|
+
"author": "grimoire-team",
|
|
32
|
+
"description": "Audita código em busca de vulnerabilidades OWASP Top 10. SAST e code review de segurança.",
|
|
33
|
+
"gist": "https://raw.githubusercontent.com/gabrielrlima/grimoire/master/marketplace/agents/security-auditor.md"
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"slug": "ml-engineer",
|
|
37
|
+
"name": "Dalí",
|
|
38
|
+
"icon": "🧠",
|
|
39
|
+
"specialty": "Machine Learning & AI",
|
|
40
|
+
"tags": [
|
|
41
|
+
"ml",
|
|
42
|
+
"python",
|
|
43
|
+
"pytorch",
|
|
44
|
+
"sklearn"
|
|
45
|
+
],
|
|
46
|
+
"author": "grimoire-team",
|
|
47
|
+
"description": "Implementa pipelines de ML, feature engineering, treinamento e avaliação de modelos.",
|
|
48
|
+
"gist": "https://raw.githubusercontent.com/gabrielrlima/grimoire/master/marketplace/agents/ml-engineer.md"
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
"slug": "api-designer",
|
|
52
|
+
"name": "Klimt",
|
|
53
|
+
"icon": "🔗",
|
|
54
|
+
"specialty": "API Design & Documentação",
|
|
55
|
+
"tags": [
|
|
56
|
+
"rest",
|
|
57
|
+
"graphql",
|
|
58
|
+
"openapi",
|
|
59
|
+
"swagger"
|
|
60
|
+
],
|
|
61
|
+
"author": "grimoire-team",
|
|
62
|
+
"description": "Projeta APIs RESTful e GraphQL. Gera documentação OpenAPI 3.x e valida contratos.",
|
|
63
|
+
"gist": "https://raw.githubusercontent.com/gabrielrlima/grimoire/master/marketplace/agents/api-designer.md"
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
"slug": "database-expert",
|
|
67
|
+
"name": "Mondrian",
|
|
68
|
+
"icon": "🗄️",
|
|
69
|
+
"specialty": "Banco de Dados & Queries",
|
|
70
|
+
"tags": [
|
|
71
|
+
"sql",
|
|
72
|
+
"postgresql",
|
|
73
|
+
"mongodb",
|
|
74
|
+
"redis"
|
|
75
|
+
],
|
|
76
|
+
"author": "grimoire-team",
|
|
77
|
+
"description": "Otimiza queries, projeta schemas e revisa migrações. PostgreSQL, MongoDB, Redis.",
|
|
78
|
+
"gist": "https://raw.githubusercontent.com/gabrielrlima/grimoire/master/marketplace/agents/database-expert.md"
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
"slug": "tech-writer",
|
|
82
|
+
"name": "Cervantes",
|
|
83
|
+
"icon": "✍️",
|
|
84
|
+
"specialty": "Documentação Técnica",
|
|
85
|
+
"tags": [
|
|
86
|
+
"docs",
|
|
87
|
+
"readme",
|
|
88
|
+
"adr",
|
|
89
|
+
"wiki"
|
|
90
|
+
],
|
|
91
|
+
"author": "grimoire-team",
|
|
92
|
+
"description": "Escreve e revisa documentação técnica: READMEs, ADRs, guias de API e wikis.",
|
|
93
|
+
"gist": "https://raw.githubusercontent.com/gabrielrlima/grimoire/master/marketplace/agents/tech-writer.md"
|
|
94
|
+
}
|
|
95
|
+
]
|
|
96
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "grimoire-framework",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.1",
|
|
4
4
|
"description": "Grimoire: AI-Orchestrated System for Full Stack Development - Core Framework",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -37,6 +37,7 @@
|
|
|
37
37
|
"GEMINI.md",
|
|
38
38
|
"pro/license/",
|
|
39
39
|
"squads/",
|
|
40
|
+
"marketplace/",
|
|
40
41
|
"README.md",
|
|
41
42
|
"LICENSE"
|
|
42
43
|
],
|
|
@@ -135,7 +135,36 @@ if (fs.existsSync(cliPath)) {
|
|
|
135
135
|
);
|
|
136
136
|
}
|
|
137
137
|
|
|
138
|
-
// ── 7.
|
|
138
|
+
// ── 7. squads/ directory ──────────────────────────────────────────────────
|
|
139
|
+
console.log('\n👥 Squads:');
|
|
140
|
+
const squadsDir = path.join(ROOT, 'squads');
|
|
141
|
+
if (fs.existsSync(squadsDir)) {
|
|
142
|
+
const squads = fs.readdirSync(squadsDir, { withFileTypes: true })
|
|
143
|
+
.filter(d => d.isDirectory()).map(d => d.name);
|
|
144
|
+
check(`squads/ directory exists (${squads.length} squads)`, squads.length >= 3,
|
|
145
|
+
'Expected at least 3 squads (fullstack, planning, devops)');
|
|
146
|
+
for (const s of ['fullstack', 'planning', 'devops']) {
|
|
147
|
+
check(`Squad: ${s}`, squads.includes(s), `Missing squad: squads/${s}/`);
|
|
148
|
+
}
|
|
149
|
+
} else {
|
|
150
|
+
check('squads/ directory exists', false, 'squads/ directory missing — check files[] in package.json');
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// ── 8. marketplace/ registry ──────────────────────────────────────────────
|
|
154
|
+
console.log('\n🏪 Marketplace:');
|
|
155
|
+
const marketplaceRegistry = path.join(ROOT, 'marketplace', 'registry.json');
|
|
156
|
+
check('marketplace/registry.json exists', fs.existsSync(marketplaceRegistry),
|
|
157
|
+
'marketplace/registry.json is missing — run: create marketplace/registry.json');
|
|
158
|
+
if (fs.existsSync(marketplaceRegistry)) {
|
|
159
|
+
try {
|
|
160
|
+
const registry = JSON.parse(fs.readFileSync(marketplaceRegistry, 'utf8'));
|
|
161
|
+
check(`registry.json has agents (found ${(registry.agents || []).length})`,
|
|
162
|
+
(registry.agents || []).length >= 1, 'registry.json should have at least 1 agent entry');
|
|
163
|
+
} catch (e) {
|
|
164
|
+
check('registry.json is valid JSON', false, `Parse error: ${e.message}`);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
139
168
|
console.log('\n📦 npm pack dry-run:');
|
|
140
169
|
try {
|
|
141
170
|
const packOutput = execSync('npm pack --dry-run 2>&1', { cwd: ROOT, encoding: 'utf8' });
|