grimoire-framework 1.0.6 → 1.0.9
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/grimoire-cli.js +208 -6
- package/package.json +1 -1
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
# - SHA256 hashes for change detection
|
|
8
8
|
# - File types for categorization
|
|
9
9
|
#
|
|
10
|
-
version: 1.0.
|
|
11
|
-
generated_at: "2026-02-
|
|
10
|
+
version: 1.0.9
|
|
11
|
+
generated_at: "2026-02-22T12:01:52.134Z"
|
|
12
12
|
generator: scripts/generate-install-manifest.js
|
|
13
13
|
file_count: 1011
|
|
14
14
|
files:
|
package/bin/grimoire-cli.js
CHANGED
|
@@ -27,8 +27,14 @@ async function main() {
|
|
|
27
27
|
case 'agents':
|
|
28
28
|
handleAgents(args.slice(1));
|
|
29
29
|
break;
|
|
30
|
+
case 'status':
|
|
31
|
+
handleStatus();
|
|
32
|
+
break;
|
|
33
|
+
case 'whoami':
|
|
34
|
+
handleWhoami();
|
|
35
|
+
break;
|
|
30
36
|
case 'doctor':
|
|
31
|
-
|
|
37
|
+
handleDoctor();
|
|
32
38
|
break;
|
|
33
39
|
case 'install':
|
|
34
40
|
case 'update':
|
|
@@ -92,6 +98,14 @@ function handleAgents(args) {
|
|
|
92
98
|
const fallbackDir = path.join(baseDir, 'node_modules', 'grimoire-framework', '.codex', 'agents');
|
|
93
99
|
const dir = fs.existsSync(agentsDir) ? agentsDir : fs.existsSync(fallbackDir) ? fallbackDir : null;
|
|
94
100
|
|
|
101
|
+
// Agent name map (id -> art persona)
|
|
102
|
+
const agentNames = {
|
|
103
|
+
'dev': 'Da Vinci', 'qa': 'Dürer', 'sm': 'Monet', 'devops': 'Boccioni',
|
|
104
|
+
'ux-design-expert': 'Matisse', 'grimoire-master': 'Michelangelo',
|
|
105
|
+
'analyst': 'Vermeer', 'architect': 'Gaudí', 'data-engineer': 'Escher',
|
|
106
|
+
'pm': 'Raphael', 'po': 'Velázquez', 'squad-creator': 'Rodin',
|
|
107
|
+
};
|
|
108
|
+
|
|
95
109
|
if (sub === 'list' || !sub) {
|
|
96
110
|
if (!dir) {
|
|
97
111
|
console.log('\n⚠️ No agents found. Run "npx grimoire-framework install" first.');
|
|
@@ -101,26 +115,214 @@ function handleAgents(args) {
|
|
|
101
115
|
.filter(f => f.endsWith('.md'))
|
|
102
116
|
.map(f => f.replace('.md', ''));
|
|
103
117
|
console.log('\n🧙 Grimoire Agents:');
|
|
104
|
-
list.forEach(a =>
|
|
105
|
-
|
|
118
|
+
list.forEach(a => {
|
|
119
|
+
const persona = agentNames[a] ? ` (${agentNames[a]})` : '';
|
|
120
|
+
console.log(` @${a}${persona}`);
|
|
121
|
+
});
|
|
122
|
+
console.log(`\n Total: ${list.length} agents | Invoke with @agentname in your IDE chat`);
|
|
106
123
|
} else {
|
|
107
124
|
console.log('Usage: grimoire agents list');
|
|
108
125
|
}
|
|
109
126
|
}
|
|
110
127
|
|
|
128
|
+
function handleStatus() {
|
|
129
|
+
const cwd = process.cwd();
|
|
130
|
+
const check = (p) => fs.existsSync(p);
|
|
131
|
+
const icon = (v) => v ? '✅' : '❌';
|
|
132
|
+
|
|
133
|
+
// Detect project root (has .codex or .grimoire)
|
|
134
|
+
const hasCodex = check(path.join(cwd, '.codex'));
|
|
135
|
+
const hasGrimoire = check(path.join(cwd, '.grimoire'));
|
|
136
|
+
const hasGemini = check(path.join(cwd, '.gemini'));
|
|
137
|
+
const hasCursor = check(path.join(cwd, '.cursor'));
|
|
138
|
+
const hasClaude = check(path.join(cwd, '.claude'));
|
|
139
|
+
|
|
140
|
+
// Hooks check
|
|
141
|
+
const settingsPath = path.join(cwd, '.gemini', 'settings.json');
|
|
142
|
+
let hooks = [];
|
|
143
|
+
let hooksActive = false;
|
|
144
|
+
if (check(settingsPath)) {
|
|
145
|
+
try {
|
|
146
|
+
const settings = JSON.parse(fs.readFileSync(settingsPath, 'utf8'));
|
|
147
|
+
const h = settings.hooks || {};
|
|
148
|
+
hooks = Object.values(h).flat().filter(hook => hook && hook.command).map(h => h.command);
|
|
149
|
+
hooksActive = hooks.length > 0;
|
|
150
|
+
} catch (e) { /* ignore */ }
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// Agents count
|
|
154
|
+
const agentsDir = path.join(cwd, '.codex', 'agents');
|
|
155
|
+
const agentCount = check(agentsDir)
|
|
156
|
+
? fs.readdirSync(agentsDir).filter(f => f.endsWith('.md')).length
|
|
157
|
+
: 0;
|
|
158
|
+
|
|
159
|
+
// Memory check
|
|
160
|
+
const memDir = path.join(cwd, '.grimoire', 'memory');
|
|
161
|
+
const hasMemory = check(memDir);
|
|
162
|
+
|
|
163
|
+
// Session log (last agent used)
|
|
164
|
+
const sessionLog = path.join(cwd, '.grimoire', 'logs', 'session.log');
|
|
165
|
+
let lastAgent = null;
|
|
166
|
+
if (check(sessionLog)) {
|
|
167
|
+
try {
|
|
168
|
+
const lines = fs.readFileSync(sessionLog, 'utf8').trim().split('\n');
|
|
169
|
+
const last = lines.filter(l => l.includes('agent:')).pop();
|
|
170
|
+
if (last) lastAgent = last.split('agent:')[1]?.trim();
|
|
171
|
+
} catch (e) { /* ignore */ }
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
console.log(`
|
|
175
|
+
🔮 Grimoire Framework Status
|
|
176
|
+
${'='.repeat(40)}
|
|
177
|
+
📎 Version: v${packageJson.version}
|
|
178
|
+
📁 Project: ${cwd}
|
|
179
|
+
|
|
180
|
+
🔧 Core
|
|
181
|
+
${icon(hasCodex)} .codex (agents & config)
|
|
182
|
+
${icon(hasGrimoire)} .grimoire (memory & metrics)
|
|
183
|
+
${icon(agentCount > 0)} Agents: ${agentCount} loaded
|
|
184
|
+
|
|
185
|
+
🪝 Hooks (Gemini CLI)
|
|
186
|
+
${icon(check(settingsPath))} settings.json
|
|
187
|
+
${icon(hooksActive)} Hooks active: ${hooksActive ? hooks.length + ' configured' : 'none found'}
|
|
188
|
+
|
|
189
|
+
💻 IDE Integration
|
|
190
|
+
${icon(hasGemini)} .gemini (Gemini CLI rules)
|
|
191
|
+
${icon(hasCursor)} .cursor (Cursor rules)
|
|
192
|
+
${icon(hasClaude)} .claude (Claude commands)
|
|
193
|
+
|
|
194
|
+
💾 Memory Layer
|
|
195
|
+
${icon(hasMemory)} Memory store ${hasMemory ? '(active)' : '(not initialized)'}
|
|
196
|
+
${lastAgent ? `
|
|
197
|
+
🧙 Last Agent: @${lastAgent}` : ''}
|
|
198
|
+
|
|
199
|
+
Run 'grimoire agents list' to see all agents.
|
|
200
|
+
Run 'grimoire whoami' to see session context.
|
|
201
|
+
`);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
function handleWhoami() {
|
|
205
|
+
const cwd = process.cwd();
|
|
206
|
+
|
|
207
|
+
// Detect IDE from environment
|
|
208
|
+
const inCursor = process.env.CURSOR_TRACE_ID || process.env.VSCODE_PID;
|
|
209
|
+
const inVSCode = process.env.VSCODE_PID && !inCursor;
|
|
210
|
+
const inGemini = process.env.GEMINI_CLI || process.env.CLOUD_SHELL;
|
|
211
|
+
const inClaude = process.env.CLAUDE_AGENT;
|
|
212
|
+
let ide = 'Unknown IDE';
|
|
213
|
+
if (inCursor) ide = 'Cursor';
|
|
214
|
+
else if (inVSCode) ide = 'VS Code';
|
|
215
|
+
else if (inGemini) ide = 'Gemini CLI';
|
|
216
|
+
else if (inClaude) ide = 'Claude';
|
|
217
|
+
|
|
218
|
+
// Detect project name
|
|
219
|
+
const projectPkg = path.join(cwd, 'package.json');
|
|
220
|
+
let projectName = path.basename(cwd);
|
|
221
|
+
if (fs.existsSync(projectPkg)) {
|
|
222
|
+
try { projectName = JSON.parse(fs.readFileSync(projectPkg, 'utf8')).name || projectName; } catch (e) { }
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// Read grimoire config if exists
|
|
226
|
+
const configPath = path.join(cwd, '.grimoire', 'config.json');
|
|
227
|
+
let config = {};
|
|
228
|
+
if (fs.existsSync(configPath)) {
|
|
229
|
+
try { config = JSON.parse(fs.readFileSync(configPath, 'utf8')); } catch (e) { }
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// Available agents with personas
|
|
233
|
+
const agentNames = {
|
|
234
|
+
'dev': 'Da Vinci', 'qa': 'Dürer', 'sm': 'Monet', 'devops': 'Boccioni',
|
|
235
|
+
'ux-design-expert': 'Matisse', 'grimoire-master': 'Michelangelo',
|
|
236
|
+
'analyst': 'Vermeer', 'architect': 'Gaudí', 'data-engineer': 'Escher',
|
|
237
|
+
'pm': 'Raphael', 'po': 'Velázquez', 'squad-creator': 'Rodin',
|
|
238
|
+
};
|
|
239
|
+
|
|
240
|
+
const agentsDir = path.join(cwd, '.codex', 'agents');
|
|
241
|
+
const availableAgents = fs.existsSync(agentsDir)
|
|
242
|
+
? fs.readdirSync(agentsDir).filter(f => f.endsWith('.md')).map(f => f.replace('.md', ''))
|
|
243
|
+
: [];
|
|
244
|
+
|
|
245
|
+
const agentList = availableAgents
|
|
246
|
+
.map(a => agentNames[a] ? `@${a} (${agentNames[a]})` : `@${a}`)
|
|
247
|
+
.join(', ');
|
|
248
|
+
|
|
249
|
+
console.log(`
|
|
250
|
+
🧙 Grimoire — Who Am I?
|
|
251
|
+
${'='.repeat(40)}
|
|
252
|
+
📌 You are: ${process.env.USER || process.env.USERNAME || 'unknown user'}
|
|
253
|
+
📂 Project: ${projectName}
|
|
254
|
+
📍 Directory: ${cwd}
|
|
255
|
+
💻 IDE: ${ide}
|
|
256
|
+
🔮 Framework: Grimoire v${packageJson.version}
|
|
257
|
+
${config.squad ? `👥 Squad: ${config.squad}` : ''}
|
|
258
|
+
|
|
259
|
+
🧙 Available Agents:
|
|
260
|
+
${agentList || '(none found — run grimoire install)'}
|
|
261
|
+
|
|
262
|
+
💡 How to activate an agent:
|
|
263
|
+
In your IDE chat, type: @dev or @qa or @grimoire-master
|
|
264
|
+
The agent will greet you by their persona name (Da Vinci, Dürer, etc.)
|
|
265
|
+
|
|
266
|
+
🔧 Framework vs CLI:
|
|
267
|
+
CLI commands → Run in terminal: grimoire status | grimoire agents list
|
|
268
|
+
Agent chat → Activate in IDE: @agentname (e.g. @dev, @qa)
|
|
269
|
+
These are DIFFERENT interfaces — the CLI manages the framework,
|
|
270
|
+
agents respond inside your IDE's AI chat window.
|
|
271
|
+
`);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
function handleDoctor() {
|
|
275
|
+
const cwd = process.cwd();
|
|
276
|
+
const check = (p) => fs.existsSync(p);
|
|
277
|
+
const ok = (v, msg) => console.log(` ${v ? '✅' : '❌'} ${msg}`);
|
|
278
|
+
|
|
279
|
+
console.log('\n🏥 Grimoire Doctor\n' + '='.repeat(40));
|
|
280
|
+
|
|
281
|
+
ok(check(path.join(cwd, '.codex', 'agents')), '.codex/agents directory exists');
|
|
282
|
+
ok(check(path.join(cwd, '.grimoire')), '.grimoire directory exists');
|
|
283
|
+
ok(check(path.join(cwd, '.gemini', 'settings.json')), '.gemini/settings.json (hooks configured)');
|
|
284
|
+
ok(check(path.join(cwd, '.gemini', 'rules')), '.gemini/rules (agent rules installed)');
|
|
285
|
+
ok(check(path.join(cwd, '.cursor', 'rules')), '.cursor/rules (Cursor integration)');
|
|
286
|
+
|
|
287
|
+
// Check package.json has grimoire
|
|
288
|
+
const pkgPath = path.join(cwd, 'package.json');
|
|
289
|
+
if (check(pkgPath)) {
|
|
290
|
+
try {
|
|
291
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
|
|
292
|
+
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
293
|
+
ok(!!deps['grimoire-framework'], 'grimoire-framework in package.json');
|
|
294
|
+
} catch (e) { ok(false, 'package.json readable'); }
|
|
295
|
+
} else {
|
|
296
|
+
ok(false, 'package.json found');
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
console.log('\n Run \'grimoire status\' for full framework state.\n');
|
|
300
|
+
}
|
|
301
|
+
|
|
111
302
|
function showHelp() {
|
|
112
303
|
console.log(`
|
|
113
|
-
|
|
304
|
+
🔮 Grimoire Framework CLI v${packageJson.version}
|
|
305
|
+
|
|
306
|
+
The CLI manages your framework. Agents live in your IDE chat.
|
|
307
|
+
(These are DIFFERENT — CLI = terminal, Agents = @agentname in IDE chat)
|
|
114
308
|
|
|
115
309
|
USAGE:
|
|
310
|
+
grimoire status # ✨ Framework health & what's active
|
|
311
|
+
grimoire whoami # 🧙 Session context & how to use agents
|
|
116
312
|
grimoire install # Install/Reset setup
|
|
117
|
-
grimoire agents list # List available agents
|
|
313
|
+
grimoire agents list # List available agents (with personas)
|
|
118
314
|
grimoire squads list # List installed squads
|
|
119
315
|
grimoire memory [sub] # Manage persistent memory
|
|
120
316
|
grimoire metrics # View productivity metrics
|
|
121
|
-
grimoire doctor # Run diagnostics
|
|
317
|
+
grimoire doctor # Run diagnostics (checks + tips)
|
|
122
318
|
grimoire --version # Show version
|
|
123
319
|
grimoire --help # Show this help
|
|
320
|
+
|
|
321
|
+
QUICK START:
|
|
322
|
+
npx grimoire-framework install # Set up in a new project
|
|
323
|
+
grimoire status # Check everything is working
|
|
324
|
+
grimoire whoami # See available agents
|
|
325
|
+
Then in your IDE chat: @dev or @qa or @grimoire-master
|
|
124
326
|
`);
|
|
125
327
|
}
|
|
126
328
|
|