grimoire-framework 1.0.15 → 1.0.17

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.
@@ -7,8 +7,8 @@
7
7
  # - SHA256 hashes for change detection
8
8
  # - File types for categorization
9
9
  #
10
- version: 1.0.15
11
- generated_at: "2026-02-22T12:55:59.388Z"
10
+ version: 1.0.17
11
+ generated_at: "2026-02-22T13:53:52.136Z"
12
12
  generator: scripts/generate-install-manifest.js
13
13
  file_count: 1011
14
14
  files:
@@ -29,6 +29,7 @@ const FRAMEWORK_SYNC_DIRS = [
29
29
  // Single files to sync (framework root → project root)
30
30
  const FRAMEWORK_SYNC_FILES = [
31
31
  { src: 'GEMINI.md', dest: 'GEMINI.md' },
32
+ { src: '.grimoire/product/templates/ide-rules/gemini-rules.md', dest: path.join('.gemini', 'rules.md') },
32
33
  ];
33
34
 
34
35
  /**
@@ -132,12 +132,22 @@ function handleStatus() {
132
132
  const check = (p) => fs.existsSync(p);
133
133
  const icon = (v) => v ? '✅' : '❌';
134
134
 
135
- // Detect project root (has .codex or .grimoire)
136
135
  const hasCodex = check(path.join(cwd, '.codex'));
137
136
  const hasGrimoire = check(path.join(cwd, '.grimoire'));
138
137
  const hasGemini = check(path.join(cwd, '.gemini'));
139
138
  const hasCursor = check(path.join(cwd, '.cursor'));
140
139
  const hasClaude = check(path.join(cwd, '.claude'));
140
+ const hasGeminiMd = check(path.join(cwd, 'GEMINI.md'));
141
+ const hasGeminiRules = check(path.join(cwd, '.gemini', 'rules.md'));
142
+
143
+ // Check GEMINI.md has correct persona
144
+ let geminiPersonaOk = false;
145
+ if (hasGeminiMd) {
146
+ try {
147
+ const content = fs.readFileSync(path.join(cwd, 'GEMINI.md'), 'utf8');
148
+ geminiPersonaOk = content.includes('Michelangelo');
149
+ } catch (e) { /* ignore */ }
150
+ }
141
151
 
142
152
  // Hooks check
143
153
  const settingsPath = path.join(cwd, '.gemini', 'settings.json');
@@ -162,44 +172,41 @@ function handleStatus() {
162
172
  const memDir = path.join(cwd, '.grimoire', 'memory');
163
173
  const hasMemory = check(memDir);
164
174
 
165
- // Session log (last agent used)
166
- const sessionLog = path.join(cwd, '.grimoire', 'logs', 'session.log');
167
- let lastAgent = null;
168
- if (check(sessionLog)) {
169
- try {
170
- const lines = fs.readFileSync(sessionLog, 'utf8').trim().split('\n');
171
- const last = lines.filter(l => l.includes('agent:')).pop();
172
- if (last) lastAgent = last.split('agent:')[1]?.trim();
173
- } catch (e) { /* ignore */ }
175
+ // Installed version vs package.json
176
+ const installedPkgPath = path.join(cwd, 'node_modules', 'grimoire-framework', 'package.json');
177
+ let installedVersion = null;
178
+ if (check(installedPkgPath)) {
179
+ try { installedVersion = JSON.parse(fs.readFileSync(installedPkgPath, 'utf8')).version; } catch (e) { }
174
180
  }
181
+ const versionMatch = installedVersion === packageJson.version;
175
182
 
176
183
  console.log(`
177
184
  🔮 Grimoire Framework Status
178
185
  ${'='.repeat(40)}
179
- 📎 Version: v${packageJson.version}
180
- 📁 Project: ${cwd}
186
+ 📎 Version: v${packageJson.version}${installedVersion && !versionMatch ? ` (project has v${installedVersion})` : ''}
187
+ 📁 Project: ${path.basename(cwd)}
181
188
 
182
189
  🔧 Core
183
190
  ${icon(hasCodex)} .codex (agents & config)
184
191
  ${icon(hasGrimoire)} .grimoire (memory & metrics)
185
192
  ${icon(agentCount > 0)} Agents: ${agentCount} loaded
186
193
 
187
- 🪝 Hooks (Gemini CLI)
188
- ${icon(check(settingsPath))} settings.json
189
- ${icon(hooksActive)} Hooks active: ${hooksActive ? hooks.length + ' configured' : 'none found'}
190
-
191
194
  💻 IDE Integration
192
- ${icon(hasGemini)} .gemini (Gemini CLI rules)
195
+ ${icon(hasGeminiMd)} GEMINI.md (Gemini CLI — primary config)
196
+ ${icon(geminiPersonaOk)} Michelangelo persona active
197
+ ${icon(hasGeminiRules)} .gemini/rules.md (compatibility fallback)
193
198
  ${icon(hasCursor)} .cursor (Cursor rules)
194
199
  ${icon(hasClaude)} .claude (Claude commands)
195
200
 
201
+ 🪝 Hooks (Gemini CLI)
202
+ ${icon(check(settingsPath))} settings.json
203
+ ${icon(hooksActive)} Hooks: ${hooksActive ? hooks.length + ' configured' : 'none'}
204
+
196
205
  💾 Memory Layer
197
206
  ${icon(hasMemory)} Memory store ${hasMemory ? '(active)' : '(not initialized)'}
198
- ${lastAgent ? `
199
- 🧙 Last Agent: @${lastAgent}` : ''}
200
207
 
201
- Run 'grimoire agents list' to see all agents.
202
- Run 'grimoire whoami' to see session context.
208
+ ${!hasGeminiMd || !geminiPersonaOk ? '⚠️ Run: npx grimoire-framework update --force to fix missing files\n' : ''} Run 'grimoire agents list' to see all agents.
209
+ Run 'grimoire doctor' for diagnostics with tips.
203
210
  `);
204
211
  }
205
212
 
@@ -276,29 +283,95 @@ ${config.squad ? `👥 Squad: ${config.squad}` : ''}
276
283
  function handleDoctor() {
277
284
  const cwd = process.cwd();
278
285
  const check = (p) => fs.existsSync(p);
279
- const ok = (v, msg) => console.log(` ${v ? '✅' : '❌'} ${msg}`);
286
+ const ok = (v, msg, hint) => {
287
+ console.log(` ${v ? '✅' : '❌'} ${msg}`);
288
+ if (!v && hint) console.log(` 💡 ${hint}`);
289
+ };
290
+ const warn = (v, msg, hint) => {
291
+ console.log(` ${v ? '✅' : '⚠️ '} ${msg}`);
292
+ if (!v && hint) console.log(` 💡 ${hint}`);
293
+ };
280
294
 
281
295
  console.log('\n🏥 Grimoire Doctor\n' + '='.repeat(40));
282
296
 
283
- ok(check(path.join(cwd, '.codex', 'agents')), '.codex/agents directory exists');
284
- ok(check(path.join(cwd, '.grimoire')), '.grimoire directory exists');
285
- ok(check(path.join(cwd, '.gemini', 'settings.json')), '.gemini/settings.json (hooks configured)');
286
- ok(check(path.join(cwd, '.gemini', 'rules')), '.gemini/rules (agent rules installed)');
287
- ok(check(path.join(cwd, '.cursor', 'rules')), '.cursor/rules (Cursor integration)');
297
+ // ── Gemini CLI Integration ──────────────────────────────────────
298
+ console.log('\n💻 Gemini CLI Integration:');
299
+ const geminiMdPath = path.join(cwd, 'GEMINI.md');
300
+ const rulesPath = path.join(cwd, '.gemini', 'rules.md');
301
+ const hasGeminiMd = check(geminiMdPath);
302
+ const hasRulesMd = check(rulesPath);
303
+
304
+ ok(hasGeminiMd, 'GEMINI.md (primary config for modern Gemini CLI)',
305
+ 'Run: npx grimoire-framework update --force');
306
+ warn(hasRulesMd, '.gemini/rules.md (compatibility fallback)',
307
+ 'Run: npx grimoire-framework update --force');
288
308
 
289
- // Check package.json has grimoire
309
+ if (hasGeminiMd) {
310
+ try {
311
+ const content = fs.readFileSync(geminiMdPath, 'utf8');
312
+ ok(content.includes('Michelangelo'), 'Michelangelo persona in GEMINI.md',
313
+ 'GEMINI.md may be outdated — run: npx grimoire-framework update --force');
314
+ ok(content.includes('@dev'), 'Agent roster in GEMINI.md',
315
+ 'GEMINI.md is missing the agent roster');
316
+ } catch (e) { ok(false, 'GEMINI.md readable'); }
317
+ }
318
+
319
+ // ── Agents ─────────────────────────────────────────────────────
320
+ console.log('\n🤖 Agents:');
321
+ const agentsDir = path.join(cwd, '.codex', 'agents');
322
+ ok(check(agentsDir), '.codex/agents directory', 'Run: npx grimoire-framework update --force');
323
+ if (check(agentsDir)) {
324
+ const agents = fs.readdirSync(agentsDir).filter(f => f.endsWith('.md'));
325
+ ok(agents.length >= 10, `Core agents installed (${agents.length} found, need ≥10)`,
326
+ 'Run: npx grimoire-framework update --force');
327
+
328
+ const requiredAgents = ['grimoire-master.md', 'dev.md', 'qa.md', 'architect.md', 'pm.md'];
329
+ for (const a of requiredAgents) {
330
+ warn(agents.includes(a), `Agent: ${a.replace('.md', '')}`);
331
+ }
332
+
333
+ // Check grimoire-master has Michelangelo
334
+ const masterPath = path.join(agentsDir, 'grimoire-master.md');
335
+ if (check(masterPath)) {
336
+ try {
337
+ const content = fs.readFileSync(masterPath, 'utf8');
338
+ ok(content.includes('Michelangelo'), 'grimoire-master has Michelangelo persona',
339
+ 'Outdated agent — run: npx grimoire-framework update --force');
340
+ } catch (e) { }
341
+ }
342
+ }
343
+
344
+ // ── Framework Package ──────────────────────────────────────────
345
+ console.log('\n📦 Package:');
290
346
  const pkgPath = path.join(cwd, 'package.json');
291
347
  if (check(pkgPath)) {
292
348
  try {
293
349
  const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
294
350
  const deps = { ...pkg.dependencies, ...pkg.devDependencies };
295
- ok(!!deps['grimoire-framework'], 'grimoire-framework in package.json');
351
+ ok(!!deps['grimoire-framework'], 'grimoire-framework in package.json',
352
+ 'Run: npm install grimoire-framework');
353
+
354
+ // Check installed version vs latest
355
+ const installedPkgPath = path.join(cwd, 'node_modules', 'grimoire-framework', 'package.json');
356
+ if (check(installedPkgPath)) {
357
+ try {
358
+ const installedVer = JSON.parse(fs.readFileSync(installedPkgPath, 'utf8')).version;
359
+ const declaredVer = (deps['grimoire-framework'] || '').replace(/[^0-9.]/g, '');
360
+ ok(true, `Installed version: v${installedVer}`);
361
+ } catch (e) { }
362
+ }
296
363
  } catch (e) { ok(false, 'package.json readable'); }
297
364
  } else {
298
365
  ok(false, 'package.json found');
299
366
  }
300
367
 
301
- console.log('\n Run \'grimoire status\' for full framework state.\n');
368
+ // ── Other IDEs ────────────────────────────────────────────────
369
+ console.log('\n🔗 Other IDE Integration:');
370
+ warn(check(path.join(cwd, '.cursor', 'rules')), '.cursor/rules (Cursor)');
371
+ warn(check(path.join(cwd, '.claude')), '.claude/ (Claude Code)');
372
+
373
+ console.log('\n Run \'grimoire status\' for full framework state.');
374
+ console.log(' Run \'npx grimoire-framework update --force\' to resync all files.\n');
302
375
  }
303
376
 
304
377
  function showHelp() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "grimoire-framework",
3
- "version": "1.0.15",
3
+ "version": "1.0.17",
4
4
  "description": "Grimoire: AI-Orchestrated System for Full Stack Development - Core Framework",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -77,7 +77,7 @@
77
77
  "validate:semantic-lint": "node scripts/semantic-lint.js",
78
78
  "manifest:ensure": "node scripts/ensure-manifest.js",
79
79
  "sync:ide:cursor": "node .grimoire/infrastructure/scripts/ide-sync/index.js sync --ide cursor",
80
- "prepublishOnly": "npm run generate:manifest && npm run validate:manifest",
80
+ "prepublishOnly": "node scripts/pre-publish-check.js && npm run generate:manifest && npm run validate:manifest",
81
81
  "prepare": "husky"
82
82
  },
83
83
  "dependencies": {
@@ -5,6 +5,10 @@
5
5
  * @module packages/installer/src/updater
6
6
  * @story Epic 7 - CLI Update Command
7
7
  * @version 1.0.0
8
+ * @deprecated Use bin/commands/update.js instead.
9
+ * The new smart update command (grimoire-framework@1.0.10+) replaces this class.
10
+ * This file is kept for backwards compatibility of the installer wizard only.
11
+ * DO NOT add new update logic here — use bin/commands/update.js.
8
12
  *
9
13
  * Features:
10
14
  * - Detects installed version vs latest available
@@ -0,0 +1,166 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ /**
5
+ * pre-publish-check.js
6
+ * Validates that all critical files are included in the npm package before publish.
7
+ * Run: node scripts/pre-publish-check.js
8
+ *
9
+ * Bloqueia o publish se arquivos críticos estiverem faltando.
10
+ */
11
+
12
+ const fs = require('fs');
13
+ const path = require('path');
14
+ const { execSync } = require('child_process');
15
+
16
+ const ROOT = path.resolve(__dirname, '..');
17
+ const PASS = '✅';
18
+ const FAIL = '❌';
19
+ const WARN = '⚠️ ';
20
+
21
+ let hasErrors = false;
22
+
23
+ function check(label, condition, errorMsg) {
24
+ if (condition) {
25
+ console.log(` ${PASS} ${label}`);
26
+ } else {
27
+ console.log(` ${FAIL} ${label}`);
28
+ console.log(` → ${errorMsg}`);
29
+ hasErrors = true;
30
+ }
31
+ }
32
+
33
+ function warn(label, condition, warnMsg) {
34
+ if (condition) {
35
+ console.log(` ${PASS} ${label}`);
36
+ } else {
37
+ console.log(` ${WARN} ${label}`);
38
+ console.log(` → ${warnMsg}`);
39
+ }
40
+ }
41
+
42
+ console.log('\n🔍 Grimoire Framework — Pre-Publish Quality Gate\n' + '='.repeat(50));
43
+
44
+ // ── 1. Critical root files ─────────────────────────────────────────────────
45
+ console.log('\n📄 Critical root files:');
46
+ check('GEMINI.md exists', fs.existsSync(path.join(ROOT, 'GEMINI.md')), 'GEMINI.md is required for Gemini CLI integration');
47
+ check('README.md exists', fs.existsSync(path.join(ROOT, 'README.md')), 'README.md missing');
48
+ check('LICENSE exists', fs.existsSync(path.join(ROOT, 'LICENSE')), 'LICENSE file missing');
49
+
50
+ // ── 2. package.json files[] validation ────────────────────────────────────
51
+ console.log('\n📦 package.json files[] field:');
52
+ const pkg = JSON.parse(fs.readFileSync(path.join(ROOT, 'package.json'), 'utf8'));
53
+ const files = pkg.files || [];
54
+
55
+ const requiredInFiles = [
56
+ 'GEMINI.md',
57
+ '.codex/',
58
+ '.gemini/',
59
+ '.cursor/',
60
+ '.grimoire/',
61
+ 'bin/',
62
+ ];
63
+
64
+ for (const required of requiredInFiles) {
65
+ check(
66
+ `files[] includes "${required}"`,
67
+ files.some(f => f === required || f.startsWith(required.replace('/', ''))),
68
+ `Add "${required}" to the "files" array in package.json`
69
+ );
70
+ }
71
+
72
+ // ── 3. Binary entry points ─────────────────────────────────────────────────
73
+ console.log('\n⚙️ Binary entry points (bin/):');
74
+ const binEntries = pkg.bin || {};
75
+ const CORRECT_CLI = 'bin/grimoire-cli.js';
76
+
77
+ for (const [name, script] of Object.entries(binEntries)) {
78
+ if (name === 'grimoire-minimal') continue; // known exception
79
+ check(
80
+ `"${name}" → ${script}`,
81
+ script === CORRECT_CLI,
82
+ `Binary "${name}" points to "${script}" but should point to "${CORRECT_CLI}"`
83
+ );
84
+ }
85
+
86
+ // ── 4. .codex/agents presence ─────────────────────────────────────────────
87
+ console.log('\n🤖 Agents (.codex/agents):');
88
+ const agentsDir = path.join(ROOT, '.codex', 'agents');
89
+ const requiredAgents = [
90
+ 'grimoire-master.md', 'dev.md', 'qa.md', 'architect.md',
91
+ 'pm.md', 'po.md', 'sm.md', 'devops.md',
92
+ 'data-engineer.md', 'analyst.md', 'ux-design-expert.md', 'squad-creator.md',
93
+ ];
94
+
95
+ if (fs.existsSync(agentsDir)) {
96
+ const existingAgents = fs.readdirSync(agentsDir);
97
+ check(
98
+ `At least ${requiredAgents.length} core agents exist (found ${existingAgents.length})`,
99
+ existingAgents.length >= requiredAgents.length,
100
+ `Expected ${requiredAgents.length} agents, found ${existingAgents.length}`
101
+ );
102
+ for (const agent of requiredAgents) {
103
+ check(
104
+ `Agent: ${agent}`,
105
+ existingAgents.includes(agent),
106
+ `Missing required agent file: .codex/agents/${agent}`
107
+ );
108
+ }
109
+ } else {
110
+ check('.codex/agents/ directory exists', false, '.codex/agents/ directory is missing');
111
+ }
112
+
113
+ // ── 5. GEMINI.md content validation ───────────────────────────────────────
114
+ console.log('\n📝 GEMINI.md content:');
115
+ const geminiMd = path.join(ROOT, 'GEMINI.md');
116
+ if (fs.existsSync(geminiMd)) {
117
+ const content = fs.readFileSync(geminiMd, 'utf8');
118
+ check('Contains Michelangelo persona', content.includes('Michelangelo'), 'GEMINI.md must define Michelangelo as default agent');
119
+ check('Contains agent roster', content.includes('@dev'), 'GEMINI.md should include agent roster');
120
+ check('Non-empty (>500 chars)', content.length > 500, 'GEMINI.md seems too short, may be incomplete');
121
+ }
122
+
123
+ // ── 6. bin/grimoire-cli.js entry point ────────────────────────────────────
124
+ console.log('\n🚀 CLI entry point:');
125
+ const cliPath = path.join(ROOT, 'bin', 'grimoire-cli.js');
126
+ if (fs.existsSync(cliPath)) {
127
+ const cliContent = fs.readFileSync(cliPath, 'utf8');
128
+ check('commands/update.js is used (not grimoireUpdater)',
129
+ cliContent.includes("require('./commands/update')"),
130
+ 'grimoire-cli.js should delegate update to commands/update.js'
131
+ );
132
+ check('No direct reference to old updater',
133
+ !cliContent.includes('grimoireUpdater'),
134
+ 'grimoire-cli.js still references old grimoireUpdater'
135
+ );
136
+ }
137
+
138
+ // ── 7. npm pack dry-run to count files ────────────────────────────────────
139
+ console.log('\n📦 npm pack dry-run:');
140
+ try {
141
+ const packOutput = execSync('npm pack --dry-run 2>&1', { cwd: ROOT, encoding: 'utf8' });
142
+ const fileCount = (packOutput.match(/npm notice \d+\.\d+[kBMG]B/g) || []).length;
143
+ warn(
144
+ `Package contains files (detected ~${fileCount} size entries)`,
145
+ fileCount > 10,
146
+ 'Very few files detected in package — check the files[] field'
147
+ );
148
+
149
+ const hasGeminiMd = packOutput.includes('GEMINI.md');
150
+ check('GEMINI.md is in the published package', hasGeminiMd, 'GEMINI.md not found in npm pack output — add to files[]');
151
+
152
+ const hasCodex = packOutput.includes('.codex/');
153
+ check('.codex/ agents are in the published package', hasCodex, '.codex/ not found in npm pack output — add to files[]');
154
+ } catch (err) {
155
+ warn('npm pack dry-run', false, `Could not run npm pack: ${err.message}`);
156
+ }
157
+
158
+ // ── Summary ────────────────────────────────────────────────────────────────
159
+ console.log('\n' + '='.repeat(50));
160
+ if (hasErrors) {
161
+ console.log('❌ Pre-publish check FAILED — fix the errors above before publishing.\n');
162
+ process.exit(1);
163
+ } else {
164
+ console.log('✅ All checks passed — safe to publish!\n');
165
+ process.exit(0);
166
+ }