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 +2 -2
- package/bin/lib/commands/install.js +185 -133
- package/package.json +1 -1
- package/packages/pikakit-extension/pikakit.vsix +0 -0
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
|
-
[](https://www.npmjs.com/package/pikakit)
|
|
8
8
|
[](https://github.com/pikakit/agent-skills)
|
|
9
9
|
[](https://github.com/pikakit/agent-skills)
|
|
10
10
|
[](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.
|
|
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}"`, {
|
|
66
|
-
|
|
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
|
-
//
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
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
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
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
|
-
|
|
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:
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
428
|
+
if (!isInteractive || FORCE) {
|
|
429
|
+
isGlobal = false; // Default to project scope
|
|
430
|
+
} else {
|
|
431
|
+
const scope = await selectScopePrompt();
|
|
391
432
|
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
433
|
+
if (!scope) {
|
|
434
|
+
fs.rmSync(tmp, { recursive: true, force: true });
|
|
435
|
+
return;
|
|
436
|
+
}
|
|
396
437
|
|
|
397
|
-
|
|
438
|
+
isGlobal = scope === "global";
|
|
439
|
+
}
|
|
398
440
|
}
|
|
399
441
|
|
|
400
442
|
// --- Select installation method ---
|
|
401
|
-
|
|
443
|
+
let installMethod;
|
|
444
|
+
if (!isInteractive || FORCE) {
|
|
445
|
+
installMethod = "symlink"; // Default to symlink
|
|
446
|
+
} else {
|
|
447
|
+
installMethod = await selectMethodPrompt();
|
|
402
448
|
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
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 (!
|
|
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
|
-
//
|
|
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
|
-
|
|
483
|
-
|
|
484
|
-
|
|
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
|
-
|
|
488
|
-
const
|
|
518
|
+
const targetWorkflowsDir = path.join(WORKSPACE, "..", "workflows");
|
|
519
|
+
const geminiDest = path.join(WORKSPACE, "..", "GEMINI.md");
|
|
489
520
|
const targetAgentsDir = path.join(WORKSPACE, "..", "agents");
|
|
490
|
-
|
|
521
|
+
const archDest = path.join(WORKSPACE, "..", "ARCHITECTURE.md");
|
|
491
522
|
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
const
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
const
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
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
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
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
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
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
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
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
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
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
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
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
|
Binary file
|