@heyai-rules/pilo-masterkit 2.1.0 → 2.2.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.
@@ -28,9 +28,11 @@ async function copyFilteredAgent(sourceDir, targetDir, stackPaths) {
28
28
  /**
29
29
  * Common doc folder setup
30
30
  */
31
- async function setupDocs(targetDir) {
31
+ async function setupDocs(targetDir, locale) {
32
32
  const docsDir = path.join(targetDir, 'docs');
33
33
  const docFolders = ['lessons', 'reports', 'plans', 'status', 'tasks', 'logs', 'walkthroughs', 'products'];
34
+ const isVi = (locale || 'vi') === 'vi';
35
+ const desc = isVi ? 'Thư mục theo chuẩn Pilo Masterkit.' : 'Standard Pilo Masterkit directory.';
34
36
 
35
37
  for (const folder of docFolders) {
36
38
  const folderPath = path.join(docsDir, folder);
@@ -42,7 +44,7 @@ async function setupDocs(targetDir) {
42
44
 
43
45
  await fs.writeFile(
44
46
  path.join(folderPath, 'README.md'),
45
- `# ${folder.toUpperCase()}\n\nThư mục theo chuẩn Pilo Masterkit.\n`
47
+ `# ${folder.toUpperCase()}\n\n${desc}\n`
46
48
  );
47
49
  }
48
50
  }
@@ -66,7 +68,7 @@ async function injectAIHost(targetDir, aiHost, config = {}) {
66
68
 
67
69
  // Prepare variables
68
70
  const name = config.agentName || "Pilo";
69
- const locale = config.locale || 'vi'; // Default to vi
71
+ const locale = config.locale || 'vi';
70
72
  const isVi = locale === 'vi';
71
73
 
72
74
  let trigger;
@@ -92,7 +94,6 @@ async function injectAIHost(targetDir, aiHost, config = {}) {
92
94
 
93
95
  const sourceDir = path.join(templatesRoot, hostConfig.src);
94
96
  for (const destFileName of hostConfig.files) {
95
- // Priority: Localized version (e.g. GEMINI.en.md), then exact match (GEMINI.md)
96
97
  let sourceFileName = destFileName;
97
98
  if (destFileName.endsWith('.md')) {
98
99
  const localizedSource = destFileName.replace('.md', '.' + locale + '.md');
@@ -109,7 +110,6 @@ async function injectAIHost(targetDir, aiHost, config = {}) {
109
110
  if (await fs.pathExists(srcFile)) {
110
111
  let content = await fs.readFile(srcFile, 'utf8');
111
112
 
112
- // Perform interpolation
113
113
  for (const [key, value] of Object.entries(vars)) {
114
114
  const regex = new RegExp(`\\$\\{${key}\\}`, 'g');
115
115
  content = content.replace(regex, value);
@@ -120,10 +120,221 @@ async function injectAIHost(targetDir, aiHost, config = {}) {
120
120
  }
121
121
  }
122
122
 
123
+ /**
124
+ * Generate PILO_WIKI.md - Bilingual custom slash commands wiki
125
+ */
126
+ async function generateWiki(targetDir, config = {}) {
127
+ const locale = config.locale || 'vi';
128
+ const isVi = locale === 'vi';
129
+ const name = config.agentName || 'Pilo';
130
+ const stacks = Array.isArray(config.stack) ? config.stack : (config.stack ? [config.stack] : []);
131
+ const deploy = config.deploy || 'custom';
132
+
133
+ // Core commands (always present)
134
+ const coreCommands = {
135
+ vi: [
136
+ { cmd: '/plan', desc: 'Lập kế hoạch chi tiết, đánh giá rủi ro trước khi thực thi.' },
137
+ { cmd: '/debug', desc: 'Sửa lỗi có hệ thống với bảng nguyên nhân gốc (Root Cause Analysis).' },
138
+ { cmd: '/status', desc: 'Kiểm tra trạng thái Agent và tiến độ công việc.' },
139
+ { cmd: '/clean-memory', desc: 'Dọn dẹp và nén ngữ cảnh làm việc, tránh "loãng" bộ nhớ.' },
140
+ { cmd: '/tdd', desc: 'Phát triển hướng kiểm thử (Test-Driven Development).' },
141
+ { cmd: '/code-review', desc: 'Đánh giá mã nguồn theo tiêu chuẩn chất lượng cao.' },
142
+ { cmd: '/enhance', desc: 'Nâng cấp và mở rộng tính năng hiện có.' },
143
+ { cmd: '/create', desc: 'Khởi tạo luồng ứng dụng mới từ đầu.' },
144
+ ],
145
+ en: [
146
+ { cmd: '/plan', desc: 'Create detailed implementation plan with risk assessment.' },
147
+ { cmd: '/debug', desc: 'Systematic debugging with Root Cause Analysis.' },
148
+ { cmd: '/status', desc: 'Check Agent status and project progress.' },
149
+ { cmd: '/clean-memory', desc: 'Clean and compress working context to avoid memory bloat.' },
150
+ { cmd: '/tdd', desc: 'Test-Driven Development workflow.' },
151
+ { cmd: '/code-review', desc: 'Code review against high-quality standards.' },
152
+ { cmd: '/enhance', desc: 'Upgrade and extend existing features.' },
153
+ { cmd: '/create', desc: 'Initialize a new application flow from scratch.' },
154
+ ]
155
+ };
156
+
157
+ // Stack-specific commands mapping
158
+ const stackCommands = {
159
+ typescript: {
160
+ vi: [
161
+ { cmd: '/ui-ux-pro-max', desc: 'Thiết kế giao diện cao cấp với React/Next.js.' },
162
+ { cmd: '/e2e', desc: 'Kiểm thử End-to-End với Playwright.' },
163
+ { cmd: '/preview', desc: 'Khởi động server phát triển cục bộ.' },
164
+ ],
165
+ en: [
166
+ { cmd: '/ui-ux-pro-max', desc: 'Premium UI/UX design with React/Next.js.' },
167
+ { cmd: '/e2e', desc: 'End-to-End testing with Playwright.' },
168
+ { cmd: '/preview', desc: 'Start local development server.' },
169
+ ]
170
+ },
171
+ python: {
172
+ vi: [
173
+ { cmd: '/python-review', desc: 'Review code Python theo PEP 8 và best practices.' },
174
+ { cmd: '/test', desc: 'Chạy test suite với pytest.' },
175
+ ],
176
+ en: [
177
+ { cmd: '/python-review', desc: 'Review Python code for PEP 8 and best practices.' },
178
+ { cmd: '/test', desc: 'Run test suite with pytest.' },
179
+ ]
180
+ },
181
+ rust: {
182
+ vi: [
183
+ { cmd: '/rust-review', desc: 'Review Rust: ownership, lifetimes, unsafe.' },
184
+ { cmd: '/rust-build', desc: 'Sửa lỗi build Rust và borrow checker.' },
185
+ { cmd: '/rust-test', desc: 'TDD workflow cho Rust với cargo test.' },
186
+ ],
187
+ en: [
188
+ { cmd: '/rust-review', desc: 'Review Rust: ownership, lifetimes, unsafe.' },
189
+ { cmd: '/rust-build', desc: 'Fix Rust build errors and borrow checker issues.' },
190
+ { cmd: '/rust-test', desc: 'TDD workflow for Rust with cargo test.' },
191
+ ]
192
+ },
193
+ mobile: {
194
+ vi: [
195
+ { cmd: '/flutter-review', desc: 'Review Flutter/Dart code cho widget và state management.' },
196
+ { cmd: '/flutter-build', desc: 'Sửa lỗi Dart analyzer và Flutter build.' },
197
+ ],
198
+ en: [
199
+ { cmd: '/flutter-review', desc: 'Review Flutter/Dart code for widgets and state management.' },
200
+ { cmd: '/flutter-build', desc: 'Fix Dart analyzer and Flutter build failures.' },
201
+ ]
202
+ },
203
+ laravel: {
204
+ vi: [
205
+ { cmd: '/verify', desc: 'Vòng lặp kiểm tra toàn diện cho Laravel.' },
206
+ ],
207
+ en: [
208
+ { cmd: '/verify', desc: 'Comprehensive verification loop for Laravel.' },
209
+ ]
210
+ },
211
+ java: {
212
+ vi: [
213
+ { cmd: '/kotlin-review', desc: 'Review Kotlin/Java code theo chuẩn idiomatic.' },
214
+ { cmd: '/gradle-build', desc: 'Sửa lỗi Gradle build cho Android/KMP.' },
215
+ ],
216
+ en: [
217
+ { cmd: '/kotlin-review', desc: 'Review Kotlin/Java code for idiomatic patterns.' },
218
+ { cmd: '/gradle-build', desc: 'Fix Gradle build errors for Android/KMP.' },
219
+ ]
220
+ },
221
+ go: {
222
+ vi: [
223
+ { cmd: '/go-review', desc: 'Review Go code: concurrency, error handling.' },
224
+ { cmd: '/go-build', desc: 'Sửa lỗi Go build và go vet.' },
225
+ { cmd: '/go-test', desc: 'Chạy table-driven tests với go test.' },
226
+ ],
227
+ en: [
228
+ { cmd: '/go-review', desc: 'Review Go code: concurrency, error handling.' },
229
+ { cmd: '/go-build', desc: 'Fix Go build errors and go vet warnings.' },
230
+ { cmd: '/go-test', desc: 'Run table-driven tests with go test.' },
231
+ ]
232
+ },
233
+ ai_agentic: {
234
+ vi: [
235
+ { cmd: '/orchestrate', desc: 'Điều phối multi-agent workflows.' },
236
+ { cmd: '/brainstorm', desc: 'Phiên Socratic cho ý tưởng và chiến lược mới.' },
237
+ ],
238
+ en: [
239
+ { cmd: '/orchestrate', desc: 'Multi-agent workflow orchestration.' },
240
+ { cmd: '/brainstorm', desc: 'Socratic session for new ideas and strategies.' },
241
+ ]
242
+ },
243
+ marketing_research: {
244
+ vi: [
245
+ { cmd: '/brainstorm', desc: 'Brainstorming có cấu trúc cho chiến lược nội dung.' },
246
+ ],
247
+ en: [
248
+ { cmd: '/brainstorm', desc: 'Structured brainstorming for content strategy.' },
249
+ ]
250
+ },
251
+ };
252
+
253
+ // Deploy-specific commands
254
+ const deployCommands = {
255
+ vercel: {
256
+ vi: [{ cmd: '/deploy', desc: 'Triển khai lên Vercel (preview + production).' }],
257
+ en: [{ cmd: '/deploy', desc: 'Deploy to Vercel (preview + production).' }]
258
+ },
259
+ gh_pages: {
260
+ vi: [{ cmd: '/deploy', desc: 'Build và đẩy lên GitHub Pages.' }],
261
+ en: [{ cmd: '/deploy', desc: 'Build and push to GitHub Pages.' }]
262
+ },
263
+ docker: {
264
+ vi: [{ cmd: '/deploy', desc: 'Build Docker image và triển khai container.' }],
265
+ en: [{ cmd: '/deploy', desc: 'Build Docker image and deploy container.' }]
266
+ },
267
+ custom: {
268
+ vi: [{ cmd: '/deploy', desc: 'Hỗ trợ chuẩn bị trước quá trình phát hành.' }],
269
+ en: [{ cmd: '/deploy', desc: 'Assist with pre-release deployment preparation.' }]
270
+ }
271
+ };
272
+
273
+ // Build the wiki content
274
+ const title = isVi
275
+ ? `# 📖 ${name} Wiki - Hệ thống Slash Commands`
276
+ : `# 📖 ${name} Wiki - Slash Commands Reference`;
277
+
278
+ const introText = isVi
279
+ ? `> Tài liệu này được tạo tự động bởi **Pilo Masterkit** dựa trên cấu hình dự án của bạn.\n> Gọi Agent bằng lệnh: \`Chào ${name}\` hoặc \`Wakeup ${name}\` để bắt đầu phiên làm việc.\n`
280
+ : `> This document was auto-generated by **Pilo Masterkit** based on your project configuration.\n> Call your Agent with: \`Hey ${name}\` or \`Wakeup ${name}\` to start a session.\n`;
281
+
282
+ const coreSectionTitle = isVi ? '## ⚙️ Lệnh Cốt lõi (Core Commands)' : '## ⚙️ Core Commands';
283
+ const coreList = coreCommands[locale].map(c => `| \`${c.cmd}\` | ${c.desc} |`).join('\n');
284
+
285
+ let stackSection = '';
286
+ const collectedStackCmds = [];
287
+ for (const s of stacks) {
288
+ const cmds = stackCommands[s];
289
+ if (cmds && cmds[locale]) {
290
+ collectedStackCmds.push(...cmds[locale]);
291
+ }
292
+ }
293
+ if (collectedStackCmds.length > 0) {
294
+ const stackTitle = isVi
295
+ ? `## 🎯 Lệnh theo Stack của bạn`
296
+ : `## 🎯 Stack-Specific Commands`;
297
+ const stackList = collectedStackCmds.map(c => `| \`${c.cmd}\` | ${c.desc} |`).join('\n');
298
+ const stackColHeader = isVi ? 'Lệnh' : 'Command';
299
+ stackSection = `\n${stackTitle}\n\n| ${stackColHeader} | ${isVi ? 'Mô tả' : 'Description'} |\n| :--- | :--- |\n${stackList}\n`;
300
+ }
301
+
302
+ let deploySection = '';
303
+ const deployCmds = deployCommands[deploy];
304
+ if (deployCmds && deployCmds[locale]) {
305
+ const deployTitle = isVi
306
+ ? `## 🚀 Lệnh Triển khai (Deploy)`
307
+ : `## 🚀 Deployment Commands`;
308
+ const deployList = deployCmds[locale].map(c => `| \`${c.cmd}\` | ${c.desc} |`).join('\n');
309
+ const deployColHeader = isVi ? 'Lệnh' : 'Command';
310
+ deploySection = `\n${deployTitle}\n\n| ${deployColHeader} | ${isVi ? 'Mô tả' : 'Description'} |\n| :--- | :--- |\n${deployList}\n`;
311
+ }
312
+
313
+ const footer = isVi
314
+ ? `\n---\n\n*© 2026 Pilo Masterkit - Điều phối tương lai với kỷ luật và tâm hồn.*\n`
315
+ : `\n---\n\n*© 2026 Pilo Masterkit - Orchestrating the future with discipline and soul.*\n`;
316
+
317
+ const wikiContent = [
318
+ title,
319
+ '',
320
+ introText,
321
+ coreSectionTitle,
322
+ '',
323
+ `| ${isVi ? 'Lệnh' : 'Command'} | ${isVi ? 'Mô tả' : 'Description'} |`,
324
+ '| :--- | :--- |',
325
+ coreList,
326
+ stackSection,
327
+ deploySection,
328
+ footer
329
+ ].join('\n');
330
+
331
+ await fs.writeFile(path.join(targetDir, 'PILO_WIKI.md'), wikiContent);
332
+ }
333
+
123
334
  /**
124
335
  * Full install (Profile All)
125
336
  */
126
- async function installProfileAll(targetDir) {
337
+ async function installProfileAll(targetDir, config = {}) {
127
338
  const sourceAgentDir = path.join(__dirname, '..', '..', '.agent');
128
339
  const targetAgentDir = path.join(targetDir, '.agent');
129
340
 
@@ -131,15 +342,15 @@ async function installProfileAll(targetDir) {
131
342
  await fs.copy(sourceAgentDir, targetAgentDir, { overwrite: true });
132
343
  }
133
344
 
134
- await setupDocs(targetDir);
345
+ await setupDocs(targetDir, config.locale);
135
346
 
136
347
  const hosts = ['claude', 'gemini', 'cursor', 'github', 'codex'];
137
348
  for (const host of hosts) {
138
349
  await injectAIHost(targetDir, host, {
139
- locale: 'vi',
350
+ locale: config.locale || 'vi',
140
351
  scope: 'Enterprise',
141
352
  type: 'Full-Stack Agentic System',
142
- agentName: 'Pilo'
353
+ agentName: config.agentName || 'Pilo'
143
354
  });
144
355
  }
145
356
  }
@@ -161,7 +372,7 @@ async function installSelective(config) {
161
372
  }
162
373
 
163
374
  await copyFilteredAgent(sourceAgentDir, targetAgentDir, Array.from(combinedStackPaths));
164
- await setupDocs(targetDir);
375
+ await setupDocs(targetDir, config.locale);
165
376
 
166
377
  if (aiHost && aiHost !== 'none') {
167
378
  await injectAIHost(targetDir, aiHost, config);
@@ -170,5 +381,6 @@ async function installSelective(config) {
170
381
 
171
382
  module.exports = {
172
383
  installProfileAll,
173
- installSelective
384
+ installSelective,
385
+ generateWiki
174
386
  };