pikakit 3.9.103 → 3.9.104

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/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  ### Transform your AI Agent into a FAANG-level engineering team
6
6
 
7
- [![npm version](https://img.shields.io/badge/npm-v3.9.103-7c3aed?style=for-the-badge&logo=npm&logoColor=white&labelColor=18181b)](https://www.npmjs.com/package/pikakit)
7
+ [![npm version](https://img.shields.io/badge/npm-v3.9.104-7c3aed?style=for-the-badge&logo=npm&logoColor=white&labelColor=18181b)](https://www.npmjs.com/package/pikakit)
8
8
  [![Skills](https://img.shields.io/badge/skills-51-06b6d4?style=for-the-badge&labelColor=18181b)](https://github.com/pikakit/agent-skills)
9
9
  [![Agents](https://img.shields.io/badge/agents-21-f59e0b?style=for-the-badge&labelColor=18181b)](https://github.com/pikakit/agent-skills)
10
10
  [![Workflows](https://img.shields.io/badge/workflows-18-10b981?style=for-the-badge&labelColor=18181b)](https://github.com/pikakit/agent-skills)
@@ -396,7 +396,7 @@ UNLICENSED — See [LICENSE](LICENSE) for details.
396
396
 
397
397
  <div align="center">
398
398
 
399
- **⚡ PikaKit v3.9.103**
399
+ **⚡ PikaKit v3.9.104**
400
400
 
401
401
  *Composable Skills · Coordinated Agents · Intelligent Execution*
402
402
 
@@ -26,6 +26,19 @@ const pkg = require('../../../package.json');
26
26
  * @param {string} spec - Skill spec (org/repo or org/repo#skill)
27
27
  */
28
28
  export async function run(spec) {
29
+ // Global timeout safety net (5 minutes)
30
+ const GLOBAL_TIMEOUT_MS = 5 * 60 * 1000;
31
+ const globalTimer = setTimeout(() => {
32
+ console.error(c.red("\n⏱ Installation timed out after 5 minutes."));
33
+ console.error(c.dim("This usually means a network issue or a hung process."));
34
+ console.error(c.dim("Try again with: npx pikakit --force"));
35
+ process.exit(1);
36
+ }, GLOBAL_TIMEOUT_MS);
37
+ globalTimer.unref(); // Don't keep process alive just for this timer
38
+
39
+ // Non-interactive mode: auto-accept defaults when stdin is not a TTY
40
+ const isInteractive = process.stdin.isTTY !== false;
41
+
29
42
  if (!spec) {
30
43
  fatal("Missing skill spec. Usage: add-skill <org/repo>");
31
44
  return;
@@ -62,8 +75,15 @@ export async function run(spec) {
62
75
 
63
76
  for (let attempt = 1; attempt <= MAX_RETRIES; attempt++) {
64
77
  try {
65
- await execAsync(`git clone --depth=1 ${url} "${tmp}"`, { timeout: 60000 });
66
- if (ref) await execAsync(`git -C "${tmp}" checkout ${ref}`, { timeout: 30000 });
78
+ await execAsync(`git clone --depth=1 ${url} "${tmp}"`, {
79
+ timeout: 60000,
80
+ maxBuffer: 10 * 1024 * 1024,
81
+ env: { ...process.env, GIT_TERMINAL_PROMPT: "0" }
82
+ });
83
+ if (ref) await execAsync(`git -C "${tmp}" checkout ${ref}`, {
84
+ timeout: 30000,
85
+ maxBuffer: 10 * 1024 * 1024
86
+ });
67
87
  lastError = null;
68
88
  break;
69
89
  } catch (err) {
@@ -257,21 +277,28 @@ export async function run(spec) {
257
277
  return a.localeCompare(b);
258
278
  });
259
279
 
260
- // Show categories in multiselect
261
- const selectedCategories = await multiselect({
262
- message: `Found ${skillsInRepo.length} skills — ${c.gray("[")}${c.cyan("Space")}${c.gray("]")}select ${c.gray("[")}${c.cyan("Enter")}${c.gray("]")}continue`,
263
- options: sortedCategories.map(cat => ({
264
- label: `${cat} (${grouped[cat].length} skills)`,
265
- value: cat
266
- })),
267
- initialValues: sortedCategories, // Pre-select all
268
- required: true
269
- });
280
+ // Non-interactive: auto-select all categories
281
+ let selectedCategories;
282
+ if (!isInteractive || FORCE) {
283
+ selectedCategories = sortedCategories;
284
+ step(c.dim(`Auto-selected all ${sortedCategories.length} categories (non-interactive mode)`));
285
+ } else {
286
+ // Show categories in multiselect
287
+ selectedCategories = await multiselect({
288
+ message: `Found ${skillsInRepo.length} skills — ${c.gray("[")}${c.cyan("Space")}${c.gray("]")}select ${c.gray("[")}${c.cyan("Enter")}${c.gray("]")}continue`,
289
+ options: sortedCategories.map(cat => ({
290
+ label: `${cat} (${grouped[cat].length} skills)`,
291
+ value: cat
292
+ })),
293
+ initialValues: sortedCategories, // Pre-select all
294
+ required: true
295
+ });
270
296
 
271
- if (isCancel(selectedCategories)) {
272
- cancel("Cancelled.");
273
- fs.rmSync(tmp, { recursive: true, force: true });
274
- return;
297
+ if (isCancel(selectedCategories)) {
298
+ cancel("Cancelled.");
299
+ fs.rmSync(tmp, { recursive: true, force: true });
300
+ return;
301
+ }
275
302
  }
276
303
 
277
304
  // Clear multiselect default summary line (inline categories wrap)
@@ -329,9 +356,10 @@ export async function run(spec) {
329
356
  { name: "Antigravity", cli: "antigravity" }
330
357
  ];
331
358
 
332
- for (const ide of vsCodeBasedIDEs) {
359
+ // Detect IDEs in parallel (not sequentially) to avoid cumulative timeout
360
+ await Promise.allSettled(vsCodeBasedIDEs.map(async (ide) => {
333
361
  try {
334
- await execAsync(`${ide.cli} --version`, { timeout: 5000 });
362
+ await execAsync(`${ide.cli} --version`, { timeout: 3000 });
335
363
  detectedIDEs.push(ide);
336
364
  } catch {
337
365
  // Fallback: check known installation paths
@@ -343,16 +371,20 @@ export async function run(spec) {
343
371
  detectedIDEs.push(ide);
344
372
  }
345
373
  }
346
- }
374
+ }));
347
375
 
348
376
  if (detectedIDEs.length > 0) {
349
- const installExt = await confirm({
350
- message: `Install PikaKit Engine extension? ${c.dim(`(${detectedIDEs.map(i => i.name).join(", ")})`)}`,
351
- initialValue: true
352
- });
353
-
354
- if (!isCancel(installExt) && installExt) {
377
+ if (!isInteractive || FORCE) {
355
378
  wantExtension = true;
379
+ } else {
380
+ const installExt = await confirm({
381
+ message: `Install PikaKit Engine extension? ${c.dim(`(${detectedIDEs.map(i => i.name).join(", ")})`)}`,
382
+ initialValue: true
383
+ });
384
+
385
+ if (!isCancel(installExt) && installExt) {
386
+ wantExtension = true;
387
+ }
356
388
  }
357
389
  }
358
390
  }
@@ -376,7 +408,13 @@ export async function run(spec) {
376
408
  // --- Select agents (Vercel-style) ---
377
409
  const { selectAgentsPrompt, selectScopePrompt, selectMethodPrompt } = await import("../ui.js");
378
410
 
379
- const selectedAgents = await selectAgentsPrompt(detectedAgents);
411
+ let selectedAgents;
412
+ if (!isInteractive || FORCE) {
413
+ selectedAgents = detectedAgents;
414
+ step(c.dim(`Auto-selected ${detectedAgents.length} agents (non-interactive mode)`));
415
+ } else {
416
+ selectedAgents = await selectAgentsPrompt(detectedAgents);
417
+ }
380
418
 
381
419
  if (!selectedAgents || selectedAgents.length === 0) {
382
420
  fs.rmSync(tmp, { recursive: true, force: true });
@@ -387,27 +425,36 @@ export async function run(spec) {
387
425
  let isGlobal = GLOBAL;
388
426
 
389
427
  if (!GLOBAL) {
390
- const scope = await selectScopePrompt();
428
+ if (!isInteractive || FORCE) {
429
+ isGlobal = false; // Default to project scope
430
+ } else {
431
+ const scope = await selectScopePrompt();
391
432
 
392
- if (!scope) {
393
- fs.rmSync(tmp, { recursive: true, force: true });
394
- return;
395
- }
433
+ if (!scope) {
434
+ fs.rmSync(tmp, { recursive: true, force: true });
435
+ return;
436
+ }
396
437
 
397
- isGlobal = scope === "global";
438
+ isGlobal = scope === "global";
439
+ }
398
440
  }
399
441
 
400
442
  // --- Select installation method ---
401
- const installMethod = await selectMethodPrompt();
443
+ let installMethod;
444
+ if (!isInteractive || FORCE) {
445
+ installMethod = "symlink"; // Default to symlink
446
+ } else {
447
+ installMethod = await selectMethodPrompt();
402
448
 
403
- if (!installMethod) {
404
- fs.rmSync(tmp, { recursive: true, force: true });
405
- return;
449
+ if (!installMethod) {
450
+ fs.rmSync(tmp, { recursive: true, force: true });
451
+ return;
452
+ }
406
453
  }
407
454
 
408
- // Confirmation (skip if --force)
409
- let shouldProceed = FORCE;
410
- if (!FORCE) {
455
+ // Confirmation (skip if --force or non-interactive)
456
+ let shouldProceed = FORCE || !isInteractive;
457
+ if (!shouldProceed) {
411
458
  shouldProceed = await confirm({ message: "Proceed with installation?", initialValue: true });
412
459
 
413
460
  if (isCancel(shouldProceed) || !shouldProceed) {
@@ -457,118 +504,120 @@ export async function run(spec) {
457
504
  // If skillsDir is .../skills, then baseAgentDir is parent (.agent)
458
505
  const baseAgentDir = skillsDir ? path.dirname(skillsDir) : path.join(tmp, ".agent");
459
506
 
460
- // Install workflows (silent)
461
- const workflowsDir = path.join(baseAgentDir, "workflows");
462
- const targetWorkflowsDir = path.join(WORKSPACE, "..", "workflows");
507
+ // --- Post-install file copy phase (wrapped in try/catch for robustness) ---
463
508
  let workflowsInstalled = 0;
464
-
465
- if (fs.existsSync(workflowsDir)) {
466
- fs.mkdirSync(targetWorkflowsDir, { recursive: true });
467
- const workflows = fs.readdirSync(workflowsDir).filter(f => f.endsWith(".md"));
468
- for (const wf of workflows) {
469
- const src = path.join(workflowsDir, wf);
470
- const dest = path.join(targetWorkflowsDir, wf);
471
- if (!fs.existsSync(dest)) {
472
- fs.copyFileSync(src, dest);
473
- workflowsInstalled++;
474
- }
475
- }
476
- }
477
-
478
- // Install GEMINI.md (silent)
479
- const geminiSrc = path.join(baseAgentDir, "GEMINI.md");
480
- const geminiDest = path.join(WORKSPACE, "..", "GEMINI.md");
481
509
  let geminiInstalled = false;
482
- if (fs.existsSync(geminiSrc) && !fs.existsSync(geminiDest)) {
483
- fs.copyFileSync(geminiSrc, geminiDest);
484
- geminiInstalled = true;
485
- }
510
+ let agentsInstalled = 0;
511
+ let archInstalled = false;
512
+ let configInstalled = false;
513
+ let metricsInstalled = false;
514
+ let policyDocsInstalled = 0;
515
+ let rulesInstalled = 0;
516
+ let sharedInstalled = false;
486
517
 
487
- // Install agents (silent)
488
- const agentsDir = path.join(baseAgentDir, "agents");
518
+ const targetWorkflowsDir = path.join(WORKSPACE, "..", "workflows");
519
+ const geminiDest = path.join(WORKSPACE, "..", "GEMINI.md");
489
520
  const targetAgentsDir = path.join(WORKSPACE, "..", "agents");
490
- let agentsInstalled = 0;
521
+ const archDest = path.join(WORKSPACE, "..", "ARCHITECTURE.md");
491
522
 
492
- if (fs.existsSync(agentsDir)) {
493
- fs.mkdirSync(targetAgentsDir, { recursive: true });
494
- const agents = fs.readdirSync(agentsDir).filter(f => f.endsWith(".md"));
495
- for (const agent of agents) {
496
- const src = path.join(agentsDir, agent);
497
- const dest = path.join(targetAgentsDir, agent);
498
- if (!fs.existsSync(dest)) {
499
- fs.copyFileSync(src, dest);
500
- agentsInstalled++;
523
+ try {
524
+ // Install workflows (silent)
525
+ const workflowsDir = path.join(baseAgentDir, "workflows");
526
+ if (fs.existsSync(workflowsDir)) {
527
+ fs.mkdirSync(targetWorkflowsDir, { recursive: true });
528
+ const workflows = fs.readdirSync(workflowsDir).filter(f => f.endsWith(".md"));
529
+ for (const wf of workflows) {
530
+ const src = path.join(workflowsDir, wf);
531
+ const dest = path.join(targetWorkflowsDir, wf);
532
+ if (!fs.existsSync(dest)) {
533
+ fs.copyFileSync(src, dest);
534
+ workflowsInstalled++;
535
+ }
501
536
  }
502
537
  }
503
- }
504
-
505
- // Install ARCHITECTURE.md (silent)
506
- const archSrc = path.join(baseAgentDir, "ARCHITECTURE.md");
507
- const archDest = path.join(WORKSPACE, "..", "ARCHITECTURE.md");
508
- let archInstalled = false;
509
- if (fs.existsSync(archSrc) && !fs.existsSync(archDest)) {
510
- fs.copyFileSync(archSrc, archDest);
511
- archInstalled = true;
512
- }
513
-
514
538
 
539
+ // Install GEMINI.md (silent)
540
+ const geminiSrc = path.join(baseAgentDir, "GEMINI.md");
541
+ if (fs.existsSync(geminiSrc) && !fs.existsSync(geminiDest)) {
542
+ fs.copyFileSync(geminiSrc, geminiDest);
543
+ geminiInstalled = true;
544
+ }
515
545
 
516
- // Install config (silent)
517
- const configDir = path.join(baseAgentDir, "config");
518
- const targetConfigDir = path.join(WORKSPACE, "..", "config");
519
- let configInstalled = false;
520
- if (fs.existsSync(configDir) && !fs.existsSync(targetConfigDir)) {
521
- fs.cpSync(configDir, targetConfigDir, { recursive: true });
522
- configInstalled = true;
523
- }
546
+ // Install agents (silent)
547
+ const agentsDir = path.join(baseAgentDir, "agents");
548
+ if (fs.existsSync(agentsDir)) {
549
+ fs.mkdirSync(targetAgentsDir, { recursive: true });
550
+ const agents = fs.readdirSync(agentsDir).filter(f => f.endsWith(".md"));
551
+ for (const agent of agents) {
552
+ const src = path.join(agentsDir, agent);
553
+ const dest = path.join(targetAgentsDir, agent);
554
+ if (!fs.existsSync(dest)) {
555
+ fs.copyFileSync(src, dest);
556
+ agentsInstalled++;
557
+ }
558
+ }
559
+ }
524
560
 
561
+ // Install ARCHITECTURE.md (silent)
562
+ const archSrc = path.join(baseAgentDir, "ARCHITECTURE.md");
563
+ if (fs.existsSync(archSrc) && !fs.existsSync(archDest)) {
564
+ fs.copyFileSync(archSrc, archDest);
565
+ archInstalled = true;
566
+ }
525
567
 
568
+ // Install config (silent)
569
+ const configDir = path.join(baseAgentDir, "config");
570
+ const targetConfigDir = path.join(WORKSPACE, "..", "config");
571
+ if (fs.existsSync(configDir) && !fs.existsSync(targetConfigDir)) {
572
+ fs.cpSync(configDir, targetConfigDir, { recursive: true });
573
+ configInstalled = true;
574
+ }
526
575
 
527
- // Install metrics (silent)
528
- const metricsDir = path.join(baseAgentDir, "metrics");
529
- const targetMetricsDir = path.join(WORKSPACE, "..", "metrics");
530
- let metricsInstalled = false;
531
- if (fs.existsSync(metricsDir) && !fs.existsSync(targetMetricsDir)) {
532
- fs.cpSync(metricsDir, targetMetricsDir, { recursive: true });
533
- metricsInstalled = true;
534
- }
576
+ // Install metrics (silent)
577
+ const metricsDir = path.join(baseAgentDir, "metrics");
578
+ const targetMetricsDir = path.join(WORKSPACE, "..", "metrics");
579
+ if (fs.existsSync(metricsDir) && !fs.existsSync(targetMetricsDir)) {
580
+ fs.cpSync(metricsDir, targetMetricsDir, { recursive: true });
581
+ metricsInstalled = true;
582
+ }
535
583
 
536
- // Install policy documents (silent)
537
- const policyDocs = ["CONTINUOUS_EXECUTION_POLICY.md", "WORKFLOW_CHAINS.md"];
538
- let policyDocsInstalled = 0;
539
- for (const doc of policyDocs) {
540
- const docSrc = path.join(baseAgentDir, doc);
541
- const docDest = path.join(WORKSPACE, "..", doc);
542
- if (fs.existsSync(docSrc) && !fs.existsSync(docDest)) {
543
- fs.copyFileSync(docSrc, docDest);
544
- policyDocsInstalled++;
584
+ // Install policy documents (silent)
585
+ const policyDocs = ["CONTINUOUS_EXECUTION_POLICY.md", "WORKFLOW_CHAINS.md"];
586
+ for (const doc of policyDocs) {
587
+ const docSrc = path.join(baseAgentDir, doc);
588
+ const docDest = path.join(WORKSPACE, "..", doc);
589
+ if (fs.existsSync(docSrc) && !fs.existsSync(docDest)) {
590
+ fs.copyFileSync(docSrc, docDest);
591
+ policyDocsInstalled++;
592
+ }
545
593
  }
546
- }
547
594
 
548
- // Install rules (silent)
549
- const rulesDir = path.join(baseAgentDir, "rules");
550
- const targetRulesDir = path.join(WORKSPACE, "..", "rules");
551
- let rulesInstalled = 0;
552
- if (fs.existsSync(rulesDir)) {
553
- fs.mkdirSync(targetRulesDir, { recursive: true });
554
- const rules = fs.readdirSync(rulesDir).filter(f => f.endsWith(".md"));
555
- for (const rule of rules) {
556
- const src = path.join(rulesDir, rule);
557
- const dest = path.join(targetRulesDir, rule);
558
- if (!fs.existsSync(dest)) {
559
- fs.copyFileSync(src, dest);
560
- rulesInstalled++;
595
+ // Install rules (silent)
596
+ const rulesDir = path.join(baseAgentDir, "rules");
597
+ const targetRulesDir = path.join(WORKSPACE, "..", "rules");
598
+ if (fs.existsSync(rulesDir)) {
599
+ fs.mkdirSync(targetRulesDir, { recursive: true });
600
+ const rules = fs.readdirSync(rulesDir).filter(f => f.endsWith(".md"));
601
+ for (const rule of rules) {
602
+ const src = path.join(rulesDir, rule);
603
+ const dest = path.join(targetRulesDir, rule);
604
+ if (!fs.existsSync(dest)) {
605
+ fs.copyFileSync(src, dest);
606
+ rulesInstalled++;
607
+ }
561
608
  }
562
609
  }
563
- }
564
610
 
565
- // Install .shared (silent)
566
- const sharedDir = path.join(tmp, ".agent", ".shared");
567
- const targetSharedDir = path.join(WORKSPACE, "..", ".shared");
568
- let sharedInstalled = false;
569
- if (fs.existsSync(sharedDir) && !fs.existsSync(targetSharedDir)) {
570
- fs.cpSync(sharedDir, targetSharedDir, { recursive: true });
571
- sharedInstalled = true;
611
+ // Install .shared (silent)
612
+ const sharedDir = path.join(tmp, ".agent", ".shared");
613
+ const targetSharedDir = path.join(WORKSPACE, "..", ".shared");
614
+ if (fs.existsSync(sharedDir) && !fs.existsSync(targetSharedDir)) {
615
+ fs.cpSync(sharedDir, targetSharedDir, { recursive: true });
616
+ sharedInstalled = true;
617
+ }
618
+ } catch (copyErr) {
619
+ step(c.yellow(`Warning: Some files failed to copy: ${copyErr.message}`), S.diamond, "yellow");
620
+ if (process.env.DEBUG) console.error(copyErr.stack);
572
621
  }
573
622
 
574
623
  // Install PikaKit Engine Extension (if user chose yes earlier)
@@ -675,4 +724,7 @@ export async function run(spec) {
675
724
  }
676
725
  ).split("\n").map(l => `${c.gray(S.branch)} ${l}`).join("\n"));
677
726
  step(`${c.green("✓")} ${c.bold("Installation Complete!")}`);
727
+
728
+ // Clear global timeout
729
+ clearTimeout(globalTimer);
678
730
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pikakit",
3
- "version": "3.9.103",
3
+ "version": "3.9.104",
4
4
  "description": "PikaKit — Install 51 skills, 18 workflows, 21 agents into your AI project. One command.",
5
5
  "license": "MIT",
6
6
  "author": "pikakit <pikakit@gmail.com>",