pikakit 3.9.102 → 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 -134
- package/bin/lib/ui.js +3 -0
- 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;
|
|
@@ -49,7 +62,6 @@ export async function run(spec) {
|
|
|
49
62
|
|
|
50
63
|
const url = `https://github.com/${org}/${repo}.git`;
|
|
51
64
|
|
|
52
|
-
stepLine();
|
|
53
65
|
step("Source: " + c.cyan(url));
|
|
54
66
|
|
|
55
67
|
const s = spinner();
|
|
@@ -63,8 +75,15 @@ export async function run(spec) {
|
|
|
63
75
|
|
|
64
76
|
for (let attempt = 1; attempt <= MAX_RETRIES; attempt++) {
|
|
65
77
|
try {
|
|
66
|
-
await execAsync(`git clone --depth=1 ${url} "${tmp}"`, {
|
|
67
|
-
|
|
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
|
+
});
|
|
68
87
|
lastError = null;
|
|
69
88
|
break;
|
|
70
89
|
} catch (err) {
|
|
@@ -258,21 +277,28 @@ export async function run(spec) {
|
|
|
258
277
|
return a.localeCompare(b);
|
|
259
278
|
});
|
|
260
279
|
|
|
261
|
-
//
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
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
|
+
});
|
|
271
296
|
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
297
|
+
if (isCancel(selectedCategories)) {
|
|
298
|
+
cancel("Cancelled.");
|
|
299
|
+
fs.rmSync(tmp, { recursive: true, force: true });
|
|
300
|
+
return;
|
|
301
|
+
}
|
|
276
302
|
}
|
|
277
303
|
|
|
278
304
|
// Clear multiselect default summary line (inline categories wrap)
|
|
@@ -330,9 +356,10 @@ export async function run(spec) {
|
|
|
330
356
|
{ name: "Antigravity", cli: "antigravity" }
|
|
331
357
|
];
|
|
332
358
|
|
|
333
|
-
|
|
359
|
+
// Detect IDEs in parallel (not sequentially) to avoid cumulative timeout
|
|
360
|
+
await Promise.allSettled(vsCodeBasedIDEs.map(async (ide) => {
|
|
334
361
|
try {
|
|
335
|
-
await execAsync(`${ide.cli} --version`, { timeout:
|
|
362
|
+
await execAsync(`${ide.cli} --version`, { timeout: 3000 });
|
|
336
363
|
detectedIDEs.push(ide);
|
|
337
364
|
} catch {
|
|
338
365
|
// Fallback: check known installation paths
|
|
@@ -344,16 +371,20 @@ export async function run(spec) {
|
|
|
344
371
|
detectedIDEs.push(ide);
|
|
345
372
|
}
|
|
346
373
|
}
|
|
347
|
-
}
|
|
374
|
+
}));
|
|
348
375
|
|
|
349
376
|
if (detectedIDEs.length > 0) {
|
|
350
|
-
|
|
351
|
-
message: `Install PikaKit Engine extension? ${c.dim(`(${detectedIDEs.map(i => i.name).join(", ")})`)}`,
|
|
352
|
-
initialValue: true
|
|
353
|
-
});
|
|
354
|
-
|
|
355
|
-
if (!isCancel(installExt) && installExt) {
|
|
377
|
+
if (!isInteractive || FORCE) {
|
|
356
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
|
+
}
|
|
357
388
|
}
|
|
358
389
|
}
|
|
359
390
|
}
|
|
@@ -377,7 +408,13 @@ export async function run(spec) {
|
|
|
377
408
|
// --- Select agents (Vercel-style) ---
|
|
378
409
|
const { selectAgentsPrompt, selectScopePrompt, selectMethodPrompt } = await import("../ui.js");
|
|
379
410
|
|
|
380
|
-
|
|
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
|
+
}
|
|
381
418
|
|
|
382
419
|
if (!selectedAgents || selectedAgents.length === 0) {
|
|
383
420
|
fs.rmSync(tmp, { recursive: true, force: true });
|
|
@@ -388,27 +425,36 @@ export async function run(spec) {
|
|
|
388
425
|
let isGlobal = GLOBAL;
|
|
389
426
|
|
|
390
427
|
if (!GLOBAL) {
|
|
391
|
-
|
|
428
|
+
if (!isInteractive || FORCE) {
|
|
429
|
+
isGlobal = false; // Default to project scope
|
|
430
|
+
} else {
|
|
431
|
+
const scope = await selectScopePrompt();
|
|
392
432
|
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
433
|
+
if (!scope) {
|
|
434
|
+
fs.rmSync(tmp, { recursive: true, force: true });
|
|
435
|
+
return;
|
|
436
|
+
}
|
|
397
437
|
|
|
398
|
-
|
|
438
|
+
isGlobal = scope === "global";
|
|
439
|
+
}
|
|
399
440
|
}
|
|
400
441
|
|
|
401
442
|
// --- Select installation method ---
|
|
402
|
-
|
|
443
|
+
let installMethod;
|
|
444
|
+
if (!isInteractive || FORCE) {
|
|
445
|
+
installMethod = "symlink"; // Default to symlink
|
|
446
|
+
} else {
|
|
447
|
+
installMethod = await selectMethodPrompt();
|
|
403
448
|
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
449
|
+
if (!installMethod) {
|
|
450
|
+
fs.rmSync(tmp, { recursive: true, force: true });
|
|
451
|
+
return;
|
|
452
|
+
}
|
|
407
453
|
}
|
|
408
454
|
|
|
409
|
-
// Confirmation (skip if --force)
|
|
410
|
-
let shouldProceed = FORCE;
|
|
411
|
-
if (!
|
|
455
|
+
// Confirmation (skip if --force or non-interactive)
|
|
456
|
+
let shouldProceed = FORCE || !isInteractive;
|
|
457
|
+
if (!shouldProceed) {
|
|
412
458
|
shouldProceed = await confirm({ message: "Proceed with installation?", initialValue: true });
|
|
413
459
|
|
|
414
460
|
if (isCancel(shouldProceed) || !shouldProceed) {
|
|
@@ -458,118 +504,120 @@ export async function run(spec) {
|
|
|
458
504
|
// If skillsDir is .../skills, then baseAgentDir is parent (.agent)
|
|
459
505
|
const baseAgentDir = skillsDir ? path.dirname(skillsDir) : path.join(tmp, ".agent");
|
|
460
506
|
|
|
461
|
-
//
|
|
462
|
-
const workflowsDir = path.join(baseAgentDir, "workflows");
|
|
463
|
-
const targetWorkflowsDir = path.join(WORKSPACE, "..", "workflows");
|
|
507
|
+
// --- Post-install file copy phase (wrapped in try/catch for robustness) ---
|
|
464
508
|
let workflowsInstalled = 0;
|
|
465
|
-
|
|
466
|
-
if (fs.existsSync(workflowsDir)) {
|
|
467
|
-
fs.mkdirSync(targetWorkflowsDir, { recursive: true });
|
|
468
|
-
const workflows = fs.readdirSync(workflowsDir).filter(f => f.endsWith(".md"));
|
|
469
|
-
for (const wf of workflows) {
|
|
470
|
-
const src = path.join(workflowsDir, wf);
|
|
471
|
-
const dest = path.join(targetWorkflowsDir, wf);
|
|
472
|
-
if (!fs.existsSync(dest)) {
|
|
473
|
-
fs.copyFileSync(src, dest);
|
|
474
|
-
workflowsInstalled++;
|
|
475
|
-
}
|
|
476
|
-
}
|
|
477
|
-
}
|
|
478
|
-
|
|
479
|
-
// Install GEMINI.md (silent)
|
|
480
|
-
const geminiSrc = path.join(baseAgentDir, "GEMINI.md");
|
|
481
|
-
const geminiDest = path.join(WORKSPACE, "..", "GEMINI.md");
|
|
482
509
|
let geminiInstalled = false;
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
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;
|
|
487
517
|
|
|
488
|
-
|
|
489
|
-
const
|
|
518
|
+
const targetWorkflowsDir = path.join(WORKSPACE, "..", "workflows");
|
|
519
|
+
const geminiDest = path.join(WORKSPACE, "..", "GEMINI.md");
|
|
490
520
|
const targetAgentsDir = path.join(WORKSPACE, "..", "agents");
|
|
491
|
-
|
|
521
|
+
const archDest = path.join(WORKSPACE, "..", "ARCHITECTURE.md");
|
|
492
522
|
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
const
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
const
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
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
|
+
}
|
|
502
536
|
}
|
|
503
537
|
}
|
|
504
|
-
}
|
|
505
|
-
|
|
506
|
-
// Install ARCHITECTURE.md (silent)
|
|
507
|
-
const archSrc = path.join(baseAgentDir, "ARCHITECTURE.md");
|
|
508
|
-
const archDest = path.join(WORKSPACE, "..", "ARCHITECTURE.md");
|
|
509
|
-
let archInstalled = false;
|
|
510
|
-
if (fs.existsSync(archSrc) && !fs.existsSync(archDest)) {
|
|
511
|
-
fs.copyFileSync(archSrc, archDest);
|
|
512
|
-
archInstalled = true;
|
|
513
|
-
}
|
|
514
|
-
|
|
515
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
|
+
}
|
|
516
545
|
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
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
|
+
}
|
|
525
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
|
+
}
|
|
526
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
|
+
}
|
|
527
575
|
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
}
|
|
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
|
+
}
|
|
536
583
|
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
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
|
+
}
|
|
546
593
|
}
|
|
547
|
-
}
|
|
548
594
|
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
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
|
+
}
|
|
562
608
|
}
|
|
563
609
|
}
|
|
564
|
-
}
|
|
565
610
|
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
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);
|
|
573
621
|
}
|
|
574
622
|
|
|
575
623
|
// Install PikaKit Engine Extension (if user chose yes earlier)
|
|
@@ -676,4 +724,7 @@ export async function run(spec) {
|
|
|
676
724
|
}
|
|
677
725
|
).split("\n").map(l => `${c.gray(S.branch)} ${l}`).join("\n"));
|
|
678
726
|
step(`${c.green("✓")} ${c.bold("Installation Complete!")}`);
|
|
727
|
+
|
|
728
|
+
// Clear global timeout
|
|
729
|
+
clearTimeout(globalTimer);
|
|
679
730
|
}
|
package/bin/lib/ui.js
CHANGED
|
@@ -154,6 +154,9 @@ export function brandedIntro(version, status = "") {
|
|
|
154
154
|
// Split banner and filter to get content lines only
|
|
155
155
|
const bannerLines = PIKAKIT_BANNER.split('\n').filter(line => line.trim() !== '');
|
|
156
156
|
|
|
157
|
+
// Add spacing from terminal prompt
|
|
158
|
+
console.log('');
|
|
159
|
+
|
|
157
160
|
// Print all banner lines with gradient
|
|
158
161
|
for (const line of bannerLines) {
|
|
159
162
|
console.log(pikaGradient(line));
|
package/package.json
CHANGED
|
Binary file
|