@synapsync/synk 1.0.0 → 1.1.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.
package/dist/cli.mjs CHANGED
@@ -15,7 +15,7 @@ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
15
15
  import { basename, dirname, isAbsolute, join, normalize, relative, resolve, sep } from "path";
16
16
  import { fileURLToPath } from "url";
17
17
  import { homedir, platform, tmpdir } from "os";
18
- import { access, cp, lstat, mkdir, mkdtemp, readFile, readdir, readlink, rm, stat, symlink, writeFile } from "fs/promises";
18
+ import { access, cp, lstat, mkdir, mkdtemp, readFile, readdir, readlink, rename, rm, stat, symlink, writeFile } from "fs/promises";
19
19
  import "crypto";
20
20
  import { execSync, spawnSync } from "child_process";
21
21
  import * as readline from "readline";
@@ -110,6 +110,17 @@ const logger = {
110
110
  console.log(` ${message}`);
111
111
  }
112
112
  };
113
+ const COGNITIVE_SUBDIRS = {
114
+ skill: "skills",
115
+ agent: "agents",
116
+ prompt: "prompts"
117
+ };
118
+ const COGNITIVE_FILE_NAMES = {
119
+ skill: "SKILL.md",
120
+ agent: "AGENT.md",
121
+ prompt: "PROMPT.md"
122
+ };
123
+ const AGENTS_DIR$1 = ".agents";
113
124
  function getOwnerRepo(parsed) {
114
125
  if (parsed.type === "local") return null;
115
126
  if (!parsed.url.startsWith("http://") && !parsed.url.startsWith("https://")) return null;
@@ -140,9 +151,14 @@ async function isRepoPrivate(owner, repo) {
140
151
  function isLocalPath(input) {
141
152
  return isAbsolute(input) || input.startsWith("./") || input.startsWith("../") || input === "." || input === ".." || /^[a-zA-Z]:[/\\]/.test(input);
142
153
  }
143
- function isDirectSkillUrl(input) {
154
+ const cognitiveFileNamesLower = new Set(Object.values(COGNITIVE_FILE_NAMES).map((n) => n.toLowerCase()));
155
+ function endsWithCognitiveFile(input) {
156
+ const lower = input.toLowerCase();
157
+ return [...cognitiveFileNamesLower].some((f) => lower.endsWith("/" + f));
158
+ }
159
+ function isDirectCognitiveUrl(input) {
144
160
  if (!input.startsWith("http://") && !input.startsWith("https://")) return false;
145
- if (!input.toLowerCase().endsWith("/skill.md")) return false;
161
+ if (!endsWithCognitiveFile(input)) return false;
146
162
  if (input.includes("github.com/") && !input.includes("raw.githubusercontent.com")) {
147
163
  if (!input.includes("/blob/") && !input.includes("/raw/")) return false;
148
164
  }
@@ -158,7 +174,7 @@ function parseSource(input) {
158
174
  localPath: resolvedPath
159
175
  };
160
176
  }
161
- if (isDirectSkillUrl(input)) return {
177
+ if (isDirectCognitiveUrl(input)) return {
162
178
  type: "direct-url",
163
179
  url: input
164
180
  };
@@ -253,7 +269,7 @@ function isWellKnownUrl(input) {
253
269
  "huggingface.co",
254
270
  "raw.githubusercontent.com"
255
271
  ].includes(parsed.hostname)) return false;
256
- if (input.toLowerCase().endsWith("/skill.md")) return false;
272
+ if (endsWithCognitiveFile(input)) return false;
257
273
  if (input.endsWith(".git")) return false;
258
274
  return true;
259
275
  } catch {
@@ -265,41 +281,86 @@ const configHome = xdgConfig ?? join(home, ".config");
265
281
  const codexHome = process.env.CODEX_HOME?.trim() || join(home, ".codex");
266
282
  const claudeHome = process.env.CLAUDE_CONFIG_DIR?.trim() || join(home, ".claude");
267
283
  const agents = {
268
- amp: {
284
+ "adal": {
285
+ name: "adal",
286
+ displayName: "AdaL",
287
+ dirs: {
288
+ skill: {
289
+ local: ".adal/skills",
290
+ global: join(join(home, ".adal"), "skills")
291
+ },
292
+ agent: {
293
+ local: ".adal/agents",
294
+ global: join(join(home, ".adal"), "agents")
295
+ },
296
+ prompt: {
297
+ local: ".adal/prompts",
298
+ global: join(join(home, ".adal"), "prompts")
299
+ }
300
+ },
301
+ detectInstalled: async () => {
302
+ return existsSync(join(home, ".adal"));
303
+ }
304
+ },
305
+ "amp": {
269
306
  name: "amp",
270
307
  displayName: "Amp",
271
- skillsDir: ".agents/skills",
272
- globalSkillsDir: join(configHome, "agents/skills"),
273
- agentsDir: ".agents/agents",
274
- globalAgentsDir: join(configHome, "agents/agents"),
275
- promptsDir: ".agents/prompts",
276
- globalPromptsDir: join(configHome, "agents/prompts"),
308
+ dirs: {
309
+ skill: {
310
+ local: ".agents/skills",
311
+ global: join(join(configHome, "agents"), "skills")
312
+ },
313
+ agent: {
314
+ local: ".agents/agents",
315
+ global: join(join(configHome, "agents"), "agents")
316
+ },
317
+ prompt: {
318
+ local: ".agents/prompts",
319
+ global: join(join(configHome, "agents"), "prompts")
320
+ }
321
+ },
277
322
  detectInstalled: async () => {
278
323
  return existsSync(join(configHome, "amp"));
279
324
  }
280
325
  },
281
- antigravity: {
326
+ "antigravity": {
282
327
  name: "antigravity",
283
328
  displayName: "Antigravity",
284
- skillsDir: ".agent/skills",
285
- globalSkillsDir: join(home, ".gemini/antigravity/skills"),
286
- agentsDir: ".agent/agents",
287
- globalAgentsDir: join(home, ".gemini/antigravity/agents"),
288
- promptsDir: ".agent/prompts",
289
- globalPromptsDir: join(home, ".gemini/antigravity/prompts"),
329
+ dirs: {
330
+ skill: {
331
+ local: ".agent/skills",
332
+ global: join(join(home, ".gemini/antigravity"), "skills")
333
+ },
334
+ agent: {
335
+ local: ".agent/agents",
336
+ global: join(join(home, ".gemini/antigravity"), "agents")
337
+ },
338
+ prompt: {
339
+ local: ".agent/prompts",
340
+ global: join(join(home, ".gemini/antigravity"), "prompts")
341
+ }
342
+ },
290
343
  detectInstalled: async () => {
291
344
  return existsSync(join(process.cwd(), ".agent")) || existsSync(join(home, ".gemini/antigravity"));
292
345
  }
293
346
  },
294
- augment: {
347
+ "augment": {
295
348
  name: "augment",
296
349
  displayName: "Augment",
297
- skillsDir: ".augment/skills",
298
- globalSkillsDir: join(home, ".augment/skills"),
299
- agentsDir: ".augment/agents",
300
- globalAgentsDir: join(home, ".augment/agents"),
301
- promptsDir: ".augment/prompts",
302
- globalPromptsDir: join(home, ".augment/prompts"),
350
+ dirs: {
351
+ skill: {
352
+ local: ".augment/skills",
353
+ global: join(join(home, ".augment"), "skills")
354
+ },
355
+ agent: {
356
+ local: ".augment/agents",
357
+ global: join(join(home, ".augment"), "agents")
358
+ },
359
+ prompt: {
360
+ local: ".augment/prompts",
361
+ global: join(join(home, ".augment"), "prompts")
362
+ }
363
+ },
303
364
  detectInstalled: async () => {
304
365
  return existsSync(join(home, ".augment"));
305
366
  }
@@ -307,64 +368,83 @@ const agents = {
307
368
  "claude-code": {
308
369
  name: "claude-code",
309
370
  displayName: "Claude Code",
310
- skillsDir: ".claude/skills",
311
- globalSkillsDir: join(claudeHome, "skills"),
312
- agentsDir: ".claude/agents",
313
- globalAgentsDir: join(claudeHome, "agents"),
314
- promptsDir: ".claude/prompts",
315
- globalPromptsDir: join(claudeHome, "prompts"),
371
+ dirs: {
372
+ skill: {
373
+ local: ".claude/skills",
374
+ global: join(claudeHome, "skills")
375
+ },
376
+ agent: {
377
+ local: ".claude/agents",
378
+ global: join(claudeHome, "agents")
379
+ },
380
+ prompt: {
381
+ local: ".claude/prompts",
382
+ global: join(claudeHome, "prompts")
383
+ }
384
+ },
316
385
  detectInstalled: async () => {
317
386
  return existsSync(claudeHome);
318
387
  }
319
388
  },
320
- openclaw: {
321
- name: "openclaw",
322
- displayName: "OpenClaw",
323
- skillsDir: "skills",
324
- globalSkillsDir: existsSync(join(home, ".openclaw")) ? join(home, ".openclaw/skills") : existsSync(join(home, ".clawdbot")) ? join(home, ".clawdbot/skills") : join(home, ".moltbot/skills"),
325
- agentsDir: "agents",
326
- globalAgentsDir: existsSync(join(home, ".openclaw")) ? join(home, ".openclaw/agents") : existsSync(join(home, ".clawdbot")) ? join(home, ".clawdbot/agents") : join(home, ".moltbot/agents"),
327
- promptsDir: "prompts",
328
- globalPromptsDir: existsSync(join(home, ".openclaw")) ? join(home, ".openclaw/prompts") : existsSync(join(home, ".clawdbot")) ? join(home, ".clawdbot/prompts") : join(home, ".moltbot/prompts"),
329
- detectInstalled: async () => {
330
- return existsSync(join(home, ".openclaw")) || existsSync(join(home, ".clawdbot")) || existsSync(join(home, ".moltbot"));
331
- }
332
- },
333
- cline: {
389
+ "cline": {
334
390
  name: "cline",
335
391
  displayName: "Cline",
336
- skillsDir: ".cline/skills",
337
- globalSkillsDir: join(home, ".cline/skills"),
338
- agentsDir: ".cline/agents",
339
- globalAgentsDir: join(home, ".cline/agents"),
340
- promptsDir: ".cline/prompts",
341
- globalPromptsDir: join(home, ".cline/prompts"),
392
+ dirs: {
393
+ skill: {
394
+ local: ".cline/skills",
395
+ global: join(join(home, ".cline"), "skills")
396
+ },
397
+ agent: {
398
+ local: ".cline/agents",
399
+ global: join(join(home, ".cline"), "agents")
400
+ },
401
+ prompt: {
402
+ local: ".cline/prompts",
403
+ global: join(join(home, ".cline"), "prompts")
404
+ }
405
+ },
342
406
  detectInstalled: async () => {
343
407
  return existsSync(join(home, ".cline"));
344
408
  }
345
409
  },
346
- codebuddy: {
410
+ "codebuddy": {
347
411
  name: "codebuddy",
348
412
  displayName: "CodeBuddy",
349
- skillsDir: ".codebuddy/skills",
350
- globalSkillsDir: join(home, ".codebuddy/skills"),
351
- agentsDir: ".codebuddy/agents",
352
- globalAgentsDir: join(home, ".codebuddy/agents"),
353
- promptsDir: ".codebuddy/prompts",
354
- globalPromptsDir: join(home, ".codebuddy/prompts"),
413
+ dirs: {
414
+ skill: {
415
+ local: ".codebuddy/skills",
416
+ global: join(join(home, ".codebuddy"), "skills")
417
+ },
418
+ agent: {
419
+ local: ".codebuddy/agents",
420
+ global: join(join(home, ".codebuddy"), "agents")
421
+ },
422
+ prompt: {
423
+ local: ".codebuddy/prompts",
424
+ global: join(join(home, ".codebuddy"), "prompts")
425
+ }
426
+ },
355
427
  detectInstalled: async () => {
356
428
  return existsSync(join(process.cwd(), ".codebuddy")) || existsSync(join(home, ".codebuddy"));
357
429
  }
358
430
  },
359
- codex: {
431
+ "codex": {
360
432
  name: "codex",
361
433
  displayName: "Codex",
362
- skillsDir: ".agents/skills",
363
- globalSkillsDir: join(codexHome, "skills"),
364
- agentsDir: ".agents/agents",
365
- globalAgentsDir: join(codexHome, "agents"),
366
- promptsDir: ".agents/prompts",
367
- globalPromptsDir: join(codexHome, "prompts"),
434
+ dirs: {
435
+ skill: {
436
+ local: ".agents/skills",
437
+ global: join(codexHome, "skills")
438
+ },
439
+ agent: {
440
+ local: ".agents/agents",
441
+ global: join(codexHome, "agents")
442
+ },
443
+ prompt: {
444
+ local: ".agents/prompts",
445
+ global: join(codexHome, "prompts")
446
+ }
447
+ },
368
448
  detectInstalled: async () => {
369
449
  return existsSync(codexHome) || existsSync("/etc/codex");
370
450
  }
@@ -372,64 +452,104 @@ const agents = {
372
452
  "command-code": {
373
453
  name: "command-code",
374
454
  displayName: "Command Code",
375
- skillsDir: ".commandcode/skills",
376
- globalSkillsDir: join(home, ".commandcode/skills"),
377
- agentsDir: ".commandcode/agents",
378
- globalAgentsDir: join(home, ".commandcode/agents"),
379
- promptsDir: ".commandcode/prompts",
380
- globalPromptsDir: join(home, ".commandcode/prompts"),
455
+ dirs: {
456
+ skill: {
457
+ local: ".commandcode/skills",
458
+ global: join(join(home, ".commandcode"), "skills")
459
+ },
460
+ agent: {
461
+ local: ".commandcode/agents",
462
+ global: join(join(home, ".commandcode"), "agents")
463
+ },
464
+ prompt: {
465
+ local: ".commandcode/prompts",
466
+ global: join(join(home, ".commandcode"), "prompts")
467
+ }
468
+ },
381
469
  detectInstalled: async () => {
382
470
  return existsSync(join(home, ".commandcode"));
383
471
  }
384
472
  },
385
- continue: {
473
+ "continue": {
386
474
  name: "continue",
387
475
  displayName: "Continue",
388
- skillsDir: ".continue/skills",
389
- globalSkillsDir: join(home, ".continue/skills"),
390
- agentsDir: ".continue/agents",
391
- globalAgentsDir: join(home, ".continue/agents"),
392
- promptsDir: ".continue/prompts",
393
- globalPromptsDir: join(home, ".continue/prompts"),
476
+ dirs: {
477
+ skill: {
478
+ local: ".continue/skills",
479
+ global: join(join(home, ".continue"), "skills")
480
+ },
481
+ agent: {
482
+ local: ".continue/agents",
483
+ global: join(join(home, ".continue"), "agents")
484
+ },
485
+ prompt: {
486
+ local: ".continue/prompts",
487
+ global: join(join(home, ".continue"), "prompts")
488
+ }
489
+ },
394
490
  detectInstalled: async () => {
395
491
  return existsSync(join(process.cwd(), ".continue")) || existsSync(join(home, ".continue"));
396
492
  }
397
493
  },
398
- crush: {
494
+ "crush": {
399
495
  name: "crush",
400
496
  displayName: "Crush",
401
- skillsDir: ".crush/skills",
402
- globalSkillsDir: join(home, ".config/crush/skills"),
403
- agentsDir: ".crush/agents",
404
- globalAgentsDir: join(home, ".config/crush/agents"),
405
- promptsDir: ".crush/prompts",
406
- globalPromptsDir: join(home, ".config/crush/prompts"),
497
+ dirs: {
498
+ skill: {
499
+ local: ".crush/skills",
500
+ global: join(join(home, ".config/crush"), "skills")
501
+ },
502
+ agent: {
503
+ local: ".crush/agents",
504
+ global: join(join(home, ".config/crush"), "agents")
505
+ },
506
+ prompt: {
507
+ local: ".crush/prompts",
508
+ global: join(join(home, ".config/crush"), "prompts")
509
+ }
510
+ },
407
511
  detectInstalled: async () => {
408
512
  return existsSync(join(home, ".config/crush"));
409
513
  }
410
514
  },
411
- cursor: {
515
+ "cursor": {
412
516
  name: "cursor",
413
517
  displayName: "Cursor",
414
- skillsDir: ".cursor/skills",
415
- globalSkillsDir: join(home, ".cursor/skills"),
416
- agentsDir: ".cursor/agents",
417
- globalAgentsDir: join(home, ".cursor/agents"),
418
- promptsDir: ".cursor/prompts",
419
- globalPromptsDir: join(home, ".cursor/prompts"),
518
+ dirs: {
519
+ skill: {
520
+ local: ".cursor/skills",
521
+ global: join(join(home, ".cursor"), "skills")
522
+ },
523
+ agent: {
524
+ local: ".cursor/agents",
525
+ global: join(join(home, ".cursor"), "agents")
526
+ },
527
+ prompt: {
528
+ local: ".cursor/prompts",
529
+ global: join(join(home, ".cursor"), "prompts")
530
+ }
531
+ },
420
532
  detectInstalled: async () => {
421
533
  return existsSync(join(home, ".cursor"));
422
534
  }
423
535
  },
424
- droid: {
536
+ "droid": {
425
537
  name: "droid",
426
538
  displayName: "Droid",
427
- skillsDir: ".factory/skills",
428
- globalSkillsDir: join(home, ".factory/skills"),
429
- agentsDir: ".factory/agents",
430
- globalAgentsDir: join(home, ".factory/agents"),
431
- promptsDir: ".factory/prompts",
432
- globalPromptsDir: join(home, ".factory/prompts"),
539
+ dirs: {
540
+ skill: {
541
+ local: ".factory/skills",
542
+ global: join(join(home, ".factory"), "skills")
543
+ },
544
+ agent: {
545
+ local: ".factory/agents",
546
+ global: join(join(home, ".factory"), "agents")
547
+ },
548
+ prompt: {
549
+ local: ".factory/prompts",
550
+ global: join(join(home, ".factory"), "prompts")
551
+ }
552
+ },
433
553
  detectInstalled: async () => {
434
554
  return existsSync(join(home, ".factory"));
435
555
  }
@@ -437,12 +557,20 @@ const agents = {
437
557
  "gemini-cli": {
438
558
  name: "gemini-cli",
439
559
  displayName: "Gemini CLI",
440
- skillsDir: ".agents/skills",
441
- globalSkillsDir: join(home, ".gemini/skills"),
442
- agentsDir: ".agents/agents",
443
- globalAgentsDir: join(home, ".gemini/agents"),
444
- promptsDir: ".agents/prompts",
445
- globalPromptsDir: join(home, ".gemini/prompts"),
560
+ dirs: {
561
+ skill: {
562
+ local: ".agents/skills",
563
+ global: join(join(home, ".gemini"), "skills")
564
+ },
565
+ agent: {
566
+ local: ".agents/agents",
567
+ global: join(join(home, ".gemini"), "agents")
568
+ },
569
+ prompt: {
570
+ local: ".agents/prompts",
571
+ global: join(join(home, ".gemini"), "prompts")
572
+ }
573
+ },
446
574
  detectInstalled: async () => {
447
575
  return existsSync(join(home, ".gemini"));
448
576
  }
@@ -450,64 +578,104 @@ const agents = {
450
578
  "github-copilot": {
451
579
  name: "github-copilot",
452
580
  displayName: "GitHub Copilot",
453
- skillsDir: ".agents/skills",
454
- globalSkillsDir: join(home, ".copilot/skills"),
455
- agentsDir: ".agents/agents",
456
- globalAgentsDir: join(home, ".copilot/agents"),
457
- promptsDir: ".agents/prompts",
458
- globalPromptsDir: join(home, ".copilot/prompts"),
581
+ dirs: {
582
+ skill: {
583
+ local: ".agents/skills",
584
+ global: join(join(home, ".copilot"), "skills")
585
+ },
586
+ agent: {
587
+ local: ".agents/agents",
588
+ global: join(join(home, ".copilot"), "agents")
589
+ },
590
+ prompt: {
591
+ local: ".agents/prompts",
592
+ global: join(join(home, ".copilot"), "prompts")
593
+ }
594
+ },
459
595
  detectInstalled: async () => {
460
596
  return existsSync(join(process.cwd(), ".github")) || existsSync(join(home, ".copilot"));
461
597
  }
462
598
  },
463
- goose: {
599
+ "goose": {
464
600
  name: "goose",
465
601
  displayName: "Goose",
466
- skillsDir: ".goose/skills",
467
- globalSkillsDir: join(configHome, "goose/skills"),
468
- agentsDir: ".goose/agents",
469
- globalAgentsDir: join(configHome, "goose/agents"),
470
- promptsDir: ".goose/prompts",
471
- globalPromptsDir: join(configHome, "goose/prompts"),
602
+ dirs: {
603
+ skill: {
604
+ local: ".goose/skills",
605
+ global: join(join(configHome, "goose"), "skills")
606
+ },
607
+ agent: {
608
+ local: ".goose/agents",
609
+ global: join(join(configHome, "goose"), "agents")
610
+ },
611
+ prompt: {
612
+ local: ".goose/prompts",
613
+ global: join(join(configHome, "goose"), "prompts")
614
+ }
615
+ },
472
616
  detectInstalled: async () => {
473
617
  return existsSync(join(configHome, "goose"));
474
618
  }
475
619
  },
476
- junie: {
477
- name: "junie",
478
- displayName: "Junie",
479
- skillsDir: ".junie/skills",
480
- globalSkillsDir: join(home, ".junie/skills"),
481
- agentsDir: ".junie/agents",
482
- globalAgentsDir: join(home, ".junie/agents"),
483
- promptsDir: ".junie/prompts",
484
- globalPromptsDir: join(home, ".junie/prompts"),
485
- detectInstalled: async () => {
486
- return existsSync(join(home, ".junie"));
487
- }
488
- },
489
620
  "iflow-cli": {
490
621
  name: "iflow-cli",
491
622
  displayName: "iFlow CLI",
492
- skillsDir: ".iflow/skills",
493
- globalSkillsDir: join(home, ".iflow/skills"),
494
- agentsDir: ".iflow/agents",
495
- globalAgentsDir: join(home, ".iflow/agents"),
496
- promptsDir: ".iflow/prompts",
497
- globalPromptsDir: join(home, ".iflow/prompts"),
623
+ dirs: {
624
+ skill: {
625
+ local: ".iflow/skills",
626
+ global: join(join(home, ".iflow"), "skills")
627
+ },
628
+ agent: {
629
+ local: ".iflow/agents",
630
+ global: join(join(home, ".iflow"), "agents")
631
+ },
632
+ prompt: {
633
+ local: ".iflow/prompts",
634
+ global: join(join(home, ".iflow"), "prompts")
635
+ }
636
+ },
498
637
  detectInstalled: async () => {
499
638
  return existsSync(join(home, ".iflow"));
500
639
  }
501
640
  },
502
- kilo: {
641
+ "junie": {
642
+ name: "junie",
643
+ displayName: "Junie",
644
+ dirs: {
645
+ skill: {
646
+ local: ".junie/skills",
647
+ global: join(join(home, ".junie"), "skills")
648
+ },
649
+ agent: {
650
+ local: ".junie/agents",
651
+ global: join(join(home, ".junie"), "agents")
652
+ },
653
+ prompt: {
654
+ local: ".junie/prompts",
655
+ global: join(join(home, ".junie"), "prompts")
656
+ }
657
+ },
658
+ detectInstalled: async () => {
659
+ return existsSync(join(home, ".junie"));
660
+ }
661
+ },
662
+ "kilo": {
503
663
  name: "kilo",
504
664
  displayName: "Kilo Code",
505
- skillsDir: ".kilocode/skills",
506
- globalSkillsDir: join(home, ".kilocode/skills"),
507
- agentsDir: ".kilocode/agents",
508
- globalAgentsDir: join(home, ".kilocode/agents"),
509
- promptsDir: ".kilocode/prompts",
510
- globalPromptsDir: join(home, ".kilocode/prompts"),
665
+ dirs: {
666
+ skill: {
667
+ local: ".kilocode/skills",
668
+ global: join(join(home, ".kilocode"), "skills")
669
+ },
670
+ agent: {
671
+ local: ".kilocode/agents",
672
+ global: join(join(home, ".kilocode"), "agents")
673
+ },
674
+ prompt: {
675
+ local: ".kilocode/prompts",
676
+ global: join(join(home, ".kilocode"), "prompts")
677
+ }
678
+ },
511
679
  detectInstalled: async () => {
512
680
  return existsSync(join(home, ".kilocode"));
513
681
  }
@@ -515,12 +683,20 @@ const agents = {
515
683
  "kimi-cli": {
516
684
  name: "kimi-cli",
517
685
  displayName: "Kimi Code CLI",
518
- skillsDir: ".agents/skills",
519
- globalSkillsDir: join(home, ".config/agents/skills"),
520
- agentsDir: ".agents/agents",
521
- globalAgentsDir: join(home, ".config/agents/agents"),
522
- promptsDir: ".agents/prompts",
523
- globalPromptsDir: join(home, ".config/agents/prompts"),
686
+ dirs: {
687
+ skill: {
688
+ local: ".agents/skills",
689
+ global: join(join(home, ".config/agents"), "skills")
690
+ },
691
+ agent: {
692
+ local: ".agents/agents",
693
+ global: join(join(home, ".config/agents"), "agents")
694
+ },
695
+ prompt: {
696
+ local: ".agents/prompts",
697
+ global: join(join(home, ".config/agents"), "prompts")
698
+ }
699
+ },
524
700
  detectInstalled: async () => {
525
701
  return existsSync(join(home, ".kimi"));
526
702
  }
@@ -528,38 +704,62 @@ const agents = {
528
704
  "kiro-cli": {
529
705
  name: "kiro-cli",
530
706
  displayName: "Kiro CLI",
531
- skillsDir: ".kiro/skills",
532
- globalSkillsDir: join(home, ".kiro/skills"),
533
- agentsDir: ".kiro/agents",
534
- globalAgentsDir: join(home, ".kiro/agents"),
535
- promptsDir: ".kiro/prompts",
536
- globalPromptsDir: join(home, ".kiro/prompts"),
707
+ dirs: {
708
+ skill: {
709
+ local: ".kiro/skills",
710
+ global: join(join(home, ".kiro"), "skills")
711
+ },
712
+ agent: {
713
+ local: ".kiro/agents",
714
+ global: join(join(home, ".kiro"), "agents")
715
+ },
716
+ prompt: {
717
+ local: ".kiro/prompts",
718
+ global: join(join(home, ".kiro"), "prompts")
719
+ }
720
+ },
537
721
  detectInstalled: async () => {
538
722
  return existsSync(join(home, ".kiro"));
539
723
  }
540
724
  },
541
- kode: {
725
+ "kode": {
542
726
  name: "kode",
543
727
  displayName: "Kode",
544
- skillsDir: ".kode/skills",
545
- globalSkillsDir: join(home, ".kode/skills"),
546
- agentsDir: ".kode/agents",
547
- globalAgentsDir: join(home, ".kode/agents"),
548
- promptsDir: ".kode/prompts",
549
- globalPromptsDir: join(home, ".kode/prompts"),
728
+ dirs: {
729
+ skill: {
730
+ local: ".kode/skills",
731
+ global: join(join(home, ".kode"), "skills")
732
+ },
733
+ agent: {
734
+ local: ".kode/agents",
735
+ global: join(join(home, ".kode"), "agents")
736
+ },
737
+ prompt: {
738
+ local: ".kode/prompts",
739
+ global: join(join(home, ".kode"), "prompts")
740
+ }
741
+ },
550
742
  detectInstalled: async () => {
551
743
  return existsSync(join(home, ".kode"));
552
744
  }
553
745
  },
554
- mcpjam: {
746
+ "mcpjam": {
555
747
  name: "mcpjam",
556
748
  displayName: "MCPJam",
557
- skillsDir: ".mcpjam/skills",
558
- globalSkillsDir: join(home, ".mcpjam/skills"),
559
- agentsDir: ".mcpjam/agents",
560
- globalAgentsDir: join(home, ".mcpjam/agents"),
561
- promptsDir: ".mcpjam/prompts",
562
- globalPromptsDir: join(home, ".mcpjam/prompts"),
749
+ dirs: {
750
+ skill: {
751
+ local: ".mcpjam/skills",
752
+ global: join(join(home, ".mcpjam"), "skills")
753
+ },
754
+ agent: {
755
+ local: ".mcpjam/agents",
756
+ global: join(join(home, ".mcpjam"), "agents")
757
+ },
758
+ prompt: {
759
+ local: ".mcpjam/prompts",
760
+ global: join(join(home, ".mcpjam"), "prompts")
761
+ }
762
+ },
563
763
  detectInstalled: async () => {
564
764
  return existsSync(join(home, ".mcpjam"));
565
765
  }
@@ -567,77 +767,188 @@ const agents = {
567
767
  "mistral-vibe": {
568
768
  name: "mistral-vibe",
569
769
  displayName: "Mistral Vibe",
570
- skillsDir: ".vibe/skills",
571
- globalSkillsDir: join(home, ".vibe/skills"),
572
- agentsDir: ".vibe/agents",
573
- globalAgentsDir: join(home, ".vibe/agents"),
574
- promptsDir: ".vibe/prompts",
575
- globalPromptsDir: join(home, ".vibe/prompts"),
770
+ dirs: {
771
+ skill: {
772
+ local: ".vibe/skills",
773
+ global: join(join(home, ".vibe"), "skills")
774
+ },
775
+ agent: {
776
+ local: ".vibe/agents",
777
+ global: join(join(home, ".vibe"), "agents")
778
+ },
779
+ prompt: {
780
+ local: ".vibe/prompts",
781
+ global: join(join(home, ".vibe"), "prompts")
782
+ }
783
+ },
576
784
  detectInstalled: async () => {
577
785
  return existsSync(join(home, ".vibe"));
578
786
  }
579
787
  },
580
- mux: {
788
+ "mux": {
581
789
  name: "mux",
582
790
  displayName: "Mux",
583
- skillsDir: ".mux/skills",
584
- globalSkillsDir: join(home, ".mux/skills"),
585
- agentsDir: ".mux/agents",
586
- globalAgentsDir: join(home, ".mux/agents"),
587
- promptsDir: ".mux/prompts",
588
- globalPromptsDir: join(home, ".mux/prompts"),
791
+ dirs: {
792
+ skill: {
793
+ local: ".mux/skills",
794
+ global: join(join(home, ".mux"), "skills")
795
+ },
796
+ agent: {
797
+ local: ".mux/agents",
798
+ global: join(join(home, ".mux"), "agents")
799
+ },
800
+ prompt: {
801
+ local: ".mux/prompts",
802
+ global: join(join(home, ".mux"), "prompts")
803
+ }
804
+ },
589
805
  detectInstalled: async () => {
590
806
  return existsSync(join(home, ".mux"));
591
807
  }
592
808
  },
593
- opencode: {
809
+ "neovate": {
810
+ name: "neovate",
811
+ displayName: "Neovate",
812
+ dirs: {
813
+ skill: {
814
+ local: ".neovate/skills",
815
+ global: join(join(home, ".neovate"), "skills")
816
+ },
817
+ agent: {
818
+ local: ".neovate/agents",
819
+ global: join(join(home, ".neovate"), "agents")
820
+ },
821
+ prompt: {
822
+ local: ".neovate/prompts",
823
+ global: join(join(home, ".neovate"), "prompts")
824
+ }
825
+ },
826
+ detectInstalled: async () => {
827
+ return existsSync(join(home, ".neovate"));
828
+ }
829
+ },
830
+ "openclaw": {
831
+ name: "openclaw",
832
+ displayName: "OpenClaw",
833
+ dirs: {
834
+ skill: {
835
+ local: "skills",
836
+ global: existsSync(join(home, ".openclaw")) ? join(join(home, ".openclaw"), "skills") : existsSync(join(home, ".clawdbot")) ? join(join(home, ".clawdbot"), "skills") : join(join(home, ".moltbot"), "skills")
837
+ },
838
+ agent: {
839
+ local: "agents",
840
+ global: existsSync(join(home, ".openclaw")) ? join(join(home, ".openclaw"), "agents") : existsSync(join(home, ".clawdbot")) ? join(join(home, ".clawdbot"), "agents") : join(join(home, ".moltbot"), "agents")
841
+ },
842
+ prompt: {
843
+ local: "prompts",
844
+ global: existsSync(join(home, ".openclaw")) ? join(join(home, ".openclaw"), "prompts") : existsSync(join(home, ".clawdbot")) ? join(join(home, ".clawdbot"), "prompts") : join(join(home, ".moltbot"), "prompts")
845
+ }
846
+ },
847
+ detectInstalled: async () => {
848
+ return existsSync(join(home, ".openclaw")) || existsSync(join(home, ".clawdbot")) || existsSync(join(home, ".moltbot"));
849
+ }
850
+ },
851
+ "opencode": {
594
852
  name: "opencode",
595
853
  displayName: "OpenCode",
596
- skillsDir: ".agents/skills",
597
- globalSkillsDir: join(configHome, "opencode/skills"),
598
- agentsDir: ".agents/agents",
599
- globalAgentsDir: join(configHome, "opencode/agents"),
600
- promptsDir: ".agents/prompts",
601
- globalPromptsDir: join(configHome, "opencode/prompts"),
854
+ dirs: {
855
+ skill: {
856
+ local: ".agents/skills",
857
+ global: join(join(configHome, "opencode"), "skills")
858
+ },
859
+ agent: {
860
+ local: ".agents/agents",
861
+ global: join(join(configHome, "opencode"), "agents")
862
+ },
863
+ prompt: {
864
+ local: ".agents/prompts",
865
+ global: join(join(configHome, "opencode"), "prompts")
866
+ }
867
+ },
602
868
  detectInstalled: async () => {
603
869
  return existsSync(join(configHome, "opencode")) || existsSync(join(claudeHome, "skills"));
604
870
  }
605
871
  },
606
- openhands: {
872
+ "openhands": {
607
873
  name: "openhands",
608
874
  displayName: "OpenHands",
609
- skillsDir: ".openhands/skills",
610
- globalSkillsDir: join(home, ".openhands/skills"),
611
- agentsDir: ".openhands/agents",
612
- globalAgentsDir: join(home, ".openhands/agents"),
613
- promptsDir: ".openhands/prompts",
614
- globalPromptsDir: join(home, ".openhands/prompts"),
875
+ dirs: {
876
+ skill: {
877
+ local: ".openhands/skills",
878
+ global: join(join(home, ".openhands"), "skills")
879
+ },
880
+ agent: {
881
+ local: ".openhands/agents",
882
+ global: join(join(home, ".openhands"), "agents")
883
+ },
884
+ prompt: {
885
+ local: ".openhands/prompts",
886
+ global: join(join(home, ".openhands"), "prompts")
887
+ }
888
+ },
615
889
  detectInstalled: async () => {
616
890
  return existsSync(join(home, ".openhands"));
617
891
  }
618
892
  },
619
- pi: {
893
+ "pi": {
620
894
  name: "pi",
621
895
  displayName: "Pi",
622
- skillsDir: ".pi/skills",
623
- globalSkillsDir: join(home, ".pi/agent/skills"),
624
- agentsDir: ".pi/agents",
625
- globalAgentsDir: join(home, ".pi/agent/agents"),
626
- promptsDir: ".pi/prompts",
627
- globalPromptsDir: join(home, ".pi/agent/prompts"),
896
+ dirs: {
897
+ skill: {
898
+ local: ".pi/skills",
899
+ global: join(join(home, ".pi/agent"), "skills")
900
+ },
901
+ agent: {
902
+ local: ".pi/agents",
903
+ global: join(join(home, ".pi/agent"), "agents")
904
+ },
905
+ prompt: {
906
+ local: ".pi/prompts",
907
+ global: join(join(home, ".pi/agent"), "prompts")
908
+ }
909
+ },
628
910
  detectInstalled: async () => {
629
911
  return existsSync(join(home, ".pi/agent"));
630
912
  }
631
913
  },
632
- qoder: {
914
+ "pochi": {
915
+ name: "pochi",
916
+ displayName: "Pochi",
917
+ dirs: {
918
+ skill: {
919
+ local: ".pochi/skills",
920
+ global: join(join(home, ".pochi"), "skills")
921
+ },
922
+ agent: {
923
+ local: ".pochi/agents",
924
+ global: join(join(home, ".pochi"), "agents")
925
+ },
926
+ prompt: {
927
+ local: ".pochi/prompts",
928
+ global: join(join(home, ".pochi"), "prompts")
929
+ }
930
+ },
931
+ detectInstalled: async () => {
932
+ return existsSync(join(home, ".pochi"));
933
+ }
934
+ },
935
+ "qoder": {
633
936
  name: "qoder",
634
937
  displayName: "Qoder",
635
- skillsDir: ".qoder/skills",
636
- globalSkillsDir: join(home, ".qoder/skills"),
637
- agentsDir: ".qoder/agents",
638
- globalAgentsDir: join(home, ".qoder/agents"),
639
- promptsDir: ".qoder/prompts",
640
- globalPromptsDir: join(home, ".qoder/prompts"),
938
+ dirs: {
939
+ skill: {
940
+ local: ".qoder/skills",
941
+ global: join(join(home, ".qoder"), "skills")
942
+ },
943
+ agent: {
944
+ local: ".qoder/agents",
945
+ global: join(join(home, ".qoder"), "agents")
946
+ },
947
+ prompt: {
948
+ local: ".qoder/prompts",
949
+ global: join(join(home, ".qoder"), "prompts")
950
+ }
951
+ },
641
952
  detectInstalled: async () => {
642
953
  return existsSync(join(home, ".qoder"));
643
954
  }
@@ -645,133 +956,150 @@ const agents = {
645
956
  "qwen-code": {
646
957
  name: "qwen-code",
647
958
  displayName: "Qwen Code",
648
- skillsDir: ".qwen/skills",
649
- globalSkillsDir: join(home, ".qwen/skills"),
650
- agentsDir: ".qwen/agents",
651
- globalAgentsDir: join(home, ".qwen/agents"),
652
- promptsDir: ".qwen/prompts",
653
- globalPromptsDir: join(home, ".qwen/prompts"),
959
+ dirs: {
960
+ skill: {
961
+ local: ".qwen/skills",
962
+ global: join(join(home, ".qwen"), "skills")
963
+ },
964
+ agent: {
965
+ local: ".qwen/agents",
966
+ global: join(join(home, ".qwen"), "agents")
967
+ },
968
+ prompt: {
969
+ local: ".qwen/prompts",
970
+ global: join(join(home, ".qwen"), "prompts")
971
+ }
972
+ },
654
973
  detectInstalled: async () => {
655
974
  return existsSync(join(home, ".qwen"));
656
975
  }
657
976
  },
658
- replit: {
977
+ "replit": {
659
978
  name: "replit",
660
979
  displayName: "Replit",
661
- skillsDir: ".agents/skills",
662
- globalSkillsDir: join(configHome, "agents/skills"),
663
- agentsDir: ".agents/agents",
664
- globalAgentsDir: join(configHome, "agents/agents"),
665
- promptsDir: ".agents/prompts",
666
- globalPromptsDir: join(configHome, "agents/prompts"),
980
+ dirs: {
981
+ skill: {
982
+ local: ".agents/skills",
983
+ global: join(join(configHome, "agents"), "skills")
984
+ },
985
+ agent: {
986
+ local: ".agents/agents",
987
+ global: join(join(configHome, "agents"), "agents")
988
+ },
989
+ prompt: {
990
+ local: ".agents/prompts",
991
+ global: join(join(configHome, "agents"), "prompts")
992
+ }
993
+ },
667
994
  showInUniversalList: false,
668
995
  detectInstalled: async () => {
669
996
  return existsSync(join(process.cwd(), ".agents"));
670
997
  }
671
998
  },
672
- roo: {
999
+ "roo": {
673
1000
  name: "roo",
674
1001
  displayName: "Roo Code",
675
- skillsDir: ".roo/skills",
676
- globalSkillsDir: join(home, ".roo/skills"),
677
- agentsDir: ".roo/agents",
678
- globalAgentsDir: join(home, ".roo/agents"),
679
- promptsDir: ".roo/prompts",
680
- globalPromptsDir: join(home, ".roo/prompts"),
1002
+ dirs: {
1003
+ skill: {
1004
+ local: ".roo/skills",
1005
+ global: join(join(home, ".roo"), "skills")
1006
+ },
1007
+ agent: {
1008
+ local: ".roo/agents",
1009
+ global: join(join(home, ".roo"), "agents")
1010
+ },
1011
+ prompt: {
1012
+ local: ".roo/prompts",
1013
+ global: join(join(home, ".roo"), "prompts")
1014
+ }
1015
+ },
681
1016
  detectInstalled: async () => {
682
1017
  return existsSync(join(home, ".roo"));
683
1018
  }
684
1019
  },
685
- trae: {
686
- name: "trae",
687
- displayName: "Trae",
688
- skillsDir: ".trae/skills",
689
- globalSkillsDir: join(home, ".trae/skills"),
690
- agentsDir: ".trae/agents",
691
- globalAgentsDir: join(home, ".trae/agents"),
692
- promptsDir: ".trae/prompts",
693
- globalPromptsDir: join(home, ".trae/prompts"),
694
- detectInstalled: async () => {
695
- return existsSync(join(home, ".trae"));
696
- }
697
- },
698
1020
  "trae-cn": {
699
1021
  name: "trae-cn",
700
1022
  displayName: "Trae CN",
701
- skillsDir: ".trae/skills",
702
- globalSkillsDir: join(home, ".trae-cn/skills"),
703
- agentsDir: ".trae/agents",
704
- globalAgentsDir: join(home, ".trae-cn/agents"),
705
- promptsDir: ".trae/prompts",
706
- globalPromptsDir: join(home, ".trae-cn/prompts"),
1023
+ dirs: {
1024
+ skill: {
1025
+ local: ".trae/skills",
1026
+ global: join(join(home, ".trae-cn"), "skills")
1027
+ },
1028
+ agent: {
1029
+ local: ".trae/agents",
1030
+ global: join(join(home, ".trae-cn"), "agents")
1031
+ },
1032
+ prompt: {
1033
+ local: ".trae/prompts",
1034
+ global: join(join(home, ".trae-cn"), "prompts")
1035
+ }
1036
+ },
707
1037
  detectInstalled: async () => {
708
1038
  return existsSync(join(home, ".trae-cn"));
709
1039
  }
710
1040
  },
711
- windsurf: {
1041
+ "trae": {
1042
+ name: "trae",
1043
+ displayName: "Trae",
1044
+ dirs: {
1045
+ skill: {
1046
+ local: ".trae/skills",
1047
+ global: join(join(home, ".trae"), "skills")
1048
+ },
1049
+ agent: {
1050
+ local: ".trae/agents",
1051
+ global: join(join(home, ".trae"), "agents")
1052
+ },
1053
+ prompt: {
1054
+ local: ".trae/prompts",
1055
+ global: join(join(home, ".trae"), "prompts")
1056
+ }
1057
+ },
1058
+ detectInstalled: async () => {
1059
+ return existsSync(join(home, ".trae"));
1060
+ }
1061
+ },
1062
+ "windsurf": {
712
1063
  name: "windsurf",
713
1064
  displayName: "Windsurf",
714
- skillsDir: ".windsurf/skills",
715
- globalSkillsDir: join(home, ".codeium/windsurf/skills"),
716
- agentsDir: ".windsurf/agents",
717
- globalAgentsDir: join(home, ".codeium/windsurf/agents"),
718
- promptsDir: ".windsurf/prompts",
719
- globalPromptsDir: join(home, ".codeium/windsurf/prompts"),
1065
+ dirs: {
1066
+ skill: {
1067
+ local: ".windsurf/skills",
1068
+ global: join(join(home, ".codeium/windsurf"), "skills")
1069
+ },
1070
+ agent: {
1071
+ local: ".windsurf/agents",
1072
+ global: join(join(home, ".codeium/windsurf"), "agents")
1073
+ },
1074
+ prompt: {
1075
+ local: ".windsurf/prompts",
1076
+ global: join(join(home, ".codeium/windsurf"), "prompts")
1077
+ }
1078
+ },
720
1079
  detectInstalled: async () => {
721
1080
  return existsSync(join(home, ".codeium/windsurf"));
722
1081
  }
723
1082
  },
724
- zencoder: {
1083
+ "zencoder": {
725
1084
  name: "zencoder",
726
1085
  displayName: "Zencoder",
727
- skillsDir: ".zencoder/skills",
728
- globalSkillsDir: join(home, ".zencoder/skills"),
729
- agentsDir: ".zencoder/agents",
730
- globalAgentsDir: join(home, ".zencoder/agents"),
731
- promptsDir: ".zencoder/prompts",
732
- globalPromptsDir: join(home, ".zencoder/prompts"),
1086
+ dirs: {
1087
+ skill: {
1088
+ local: ".zencoder/skills",
1089
+ global: join(join(home, ".zencoder"), "skills")
1090
+ },
1091
+ agent: {
1092
+ local: ".zencoder/agents",
1093
+ global: join(join(home, ".zencoder"), "agents")
1094
+ },
1095
+ prompt: {
1096
+ local: ".zencoder/prompts",
1097
+ global: join(join(home, ".zencoder"), "prompts")
1098
+ }
1099
+ },
733
1100
  detectInstalled: async () => {
734
1101
  return existsSync(join(home, ".zencoder"));
735
1102
  }
736
- },
737
- neovate: {
738
- name: "neovate",
739
- displayName: "Neovate",
740
- skillsDir: ".neovate/skills",
741
- globalSkillsDir: join(home, ".neovate/skills"),
742
- agentsDir: ".neovate/agents",
743
- globalAgentsDir: join(home, ".neovate/agents"),
744
- promptsDir: ".neovate/prompts",
745
- globalPromptsDir: join(home, ".neovate/prompts"),
746
- detectInstalled: async () => {
747
- return existsSync(join(home, ".neovate"));
748
- }
749
- },
750
- pochi: {
751
- name: "pochi",
752
- displayName: "Pochi",
753
- skillsDir: ".pochi/skills",
754
- globalSkillsDir: join(home, ".pochi/skills"),
755
- agentsDir: ".pochi/agents",
756
- globalAgentsDir: join(home, ".pochi/agents"),
757
- promptsDir: ".pochi/prompts",
758
- globalPromptsDir: join(home, ".pochi/prompts"),
759
- detectInstalled: async () => {
760
- return existsSync(join(home, ".pochi"));
761
- }
762
- },
763
- adal: {
764
- name: "adal",
765
- displayName: "AdaL",
766
- skillsDir: ".adal/skills",
767
- globalSkillsDir: join(home, ".adal/skills"),
768
- agentsDir: ".adal/agents",
769
- globalAgentsDir: join(home, ".adal/agents"),
770
- promptsDir: ".adal/prompts",
771
- globalPromptsDir: join(home, ".adal/prompts"),
772
- detectInstalled: async () => {
773
- return existsSync(join(home, ".adal"));
774
- }
775
1103
  }
776
1104
  };
777
1105
  async function detectInstalledAgents() {
@@ -780,55 +1108,29 @@ async function detectInstalledAgents() {
780
1108
  installed: await config.detectInstalled()
781
1109
  })))).filter((r) => r.installed).map((r) => r.type);
782
1110
  }
783
- const AGENTS_DIR$3 = ".agents";
784
- const COGNITIVE_SUBDIRS = {
785
- skill: "skills",
786
- agent: "agents",
787
- prompt: "prompts"
788
- };
789
- const COGNITIVE_FILE_NAMES = {
790
- skill: "SKILL.md",
791
- agent: "AGENT.md",
792
- prompt: "PROMPT.md"
793
- };
794
- function getUniversalAgents() {
795
- return Object.entries(agents).filter(([_, config]) => config.skillsDir === ".agents/skills" && config.showInUniversalList !== false).map(([type]) => type);
1111
+ function getUniversalAgents(cognitiveType = "skill") {
1112
+ return Object.entries(agents).filter(([_, config]) => config.dirs[cognitiveType].local === `.agents/${COGNITIVE_SUBDIRS[cognitiveType]}` && config.showInUniversalList !== false).map(([type]) => type);
796
1113
  }
797
- function getNonUniversalAgents() {
798
- return Object.entries(agents).filter(([_, config]) => config.skillsDir !== ".agents/skills").map(([type]) => type);
1114
+ function getNonUniversalAgents(cognitiveType = "skill") {
1115
+ return Object.entries(agents).filter(([_, config]) => config.dirs[cognitiveType].local !== `.agents/${COGNITIVE_SUBDIRS[cognitiveType]}`).map(([type]) => type);
799
1116
  }
800
- function isUniversalAgent(type) {
801
- return agents[type].skillsDir === ".agents/skills";
1117
+ function isUniversalAgent(type, cognitiveType = "skill") {
1118
+ return agents[type].dirs[cognitiveType].local === `.agents/${COGNITIVE_SUBDIRS[cognitiveType]}`;
802
1119
  }
803
1120
  function getCognitiveDir(agentType, cognitiveType, scope) {
804
- const agent = agents[agentType];
805
- if (scope === "global") switch (cognitiveType) {
806
- case "skill": return agent.globalSkillsDir;
807
- case "agent": return agent.globalAgentsDir;
808
- case "prompt": return agent.globalPromptsDir;
809
- }
810
- else switch (cognitiveType) {
811
- case "skill": return agent.skillsDir;
812
- case "agent": return agent.agentsDir;
813
- case "prompt": return agent.promptsDir;
814
- }
1121
+ const dirEntry = agents[agentType].dirs[cognitiveType];
1122
+ return scope === "global" ? dirEntry.global : dirEntry.local;
815
1123
  }
816
1124
  function isUniversalForType(agentType, cognitiveType) {
817
- const agent = agents[agentType];
818
- const universalDir = `.agents/${COGNITIVE_SUBDIRS[cognitiveType]}`;
819
- switch (cognitiveType) {
820
- case "skill": return agent.skillsDir === universalDir;
821
- case "agent": return agent.agentsDir === universalDir;
822
- case "prompt": return agent.promptsDir === universalDir;
823
- }
1125
+ return agents[agentType].dirs[cognitiveType].local === `.agents/${COGNITIVE_SUBDIRS[cognitiveType]}`;
824
1126
  }
825
- function shortenPath$1(fullPath, cwd) {
1127
+ function shortenPath(fullPath, cwd) {
826
1128
  const home = homedir();
827
1129
  if (fullPath === home || fullPath.startsWith(home + sep)) return "~" + fullPath.slice(home.length);
828
1130
  if (fullPath === cwd || fullPath.startsWith(cwd + sep)) return "." + fullPath.slice(cwd.length);
829
1131
  return fullPath;
830
1132
  }
831
- function formatList$1(items, maxShow = 5) {
1133
+ function formatList(items, maxShow = 5) {
832
1134
  if (items.length <= maxShow) return items.join(", ");
833
1135
  const shown = items.slice(0, maxShow);
834
1136
  const remaining = items.length - maxShow;
@@ -848,11 +1150,11 @@ function buildAgentSummaryLines(targetAgents, installMode) {
848
1150
  const lines = [];
849
1151
  const { universal, symlinked } = splitAgentsByType(targetAgents);
850
1152
  if (installMode === "symlink") {
851
- if (universal.length > 0) lines.push(` ${import_picocolors.default.green("universal:")} ${formatList$1(universal)}`);
852
- if (symlinked.length > 0) lines.push(` ${import_picocolors.default.dim("symlink →")} ${formatList$1(symlinked)}`);
1153
+ if (universal.length > 0) lines.push(` ${import_picocolors.default.green("universal:")} ${formatList(universal)}`);
1154
+ if (symlinked.length > 0) lines.push(` ${import_picocolors.default.dim("symlink →")} ${formatList(symlinked)}`);
853
1155
  } else {
854
1156
  const allNames = targetAgents.map((a) => agents[a].displayName);
855
- lines.push(` ${import_picocolors.default.dim("copy →")} ${formatList$1(allNames)}`);
1157
+ lines.push(` ${import_picocolors.default.dim("copy →")} ${formatList(allNames)}`);
856
1158
  }
857
1159
  return lines;
858
1160
  }
@@ -867,31 +1169,62 @@ function buildResultLines(results, targetAgents) {
867
1169
  const { universal, symlinked: symlinkAgents } = splitAgentsByType(targetAgents);
868
1170
  const successfulSymlinks = results.filter((r) => !r.symlinkFailed && !universal.includes(r.agent)).map((r) => r.agent);
869
1171
  const failedSymlinks = results.filter((r) => r.symlinkFailed).map((r) => r.agent);
870
- if (universal.length > 0) lines.push(` ${import_picocolors.default.green("universal:")} ${formatList$1(universal)}`);
871
- if (successfulSymlinks.length > 0) lines.push(` ${import_picocolors.default.dim("symlinked:")} ${formatList$1(successfulSymlinks)}`);
872
- if (failedSymlinks.length > 0) lines.push(` ${import_picocolors.default.yellow("copied:")} ${formatList$1(failedSymlinks)}`);
1172
+ if (universal.length > 0) lines.push(` ${import_picocolors.default.green("universal:")} ${formatList(universal)}`);
1173
+ if (successfulSymlinks.length > 0) lines.push(` ${import_picocolors.default.dim("symlinked:")} ${formatList(successfulSymlinks)}`);
1174
+ if (failedSymlinks.length > 0) lines.push(` ${import_picocolors.default.yellow("copied:")} ${formatList(failedSymlinks)}`);
873
1175
  return lines;
874
1176
  }
875
- const AGENTS_DIR$2 = ".agents";
876
- const LOCK_FILE$2 = ".skill-lock.json";
1177
+ const AGENTS_DIR = ".agents";
1178
+ const LOCK_FILE = ".synk-lock.json";
1179
+ const OLD_LOCK_FILE = ".skill-lock.json";
877
1180
  const CURRENT_VERSION = 4;
878
- function getSkillLockPath$2() {
879
- return join(homedir(), AGENTS_DIR$2, LOCK_FILE$2);
1181
+ function getLockFilePath() {
1182
+ return join(homedir(), AGENTS_DIR, LOCK_FILE);
1183
+ }
1184
+ async function migrateLockFileIfNeeded() {
1185
+ const newPath = join(homedir(), AGENTS_DIR, LOCK_FILE);
1186
+ const oldPath = join(homedir(), AGENTS_DIR, OLD_LOCK_FILE);
1187
+ try {
1188
+ await stat(newPath);
1189
+ return;
1190
+ } catch {}
1191
+ try {
1192
+ await stat(oldPath);
1193
+ await rename(oldPath, newPath);
1194
+ } catch {}
880
1195
  }
881
- async function readSkillLock$2() {
882
- const lockPath = getSkillLockPath$2();
1196
+ async function readLockFile() {
1197
+ await migrateLockFileIfNeeded();
1198
+ const lockPath = getLockFilePath();
883
1199
  try {
884
1200
  const content = await readFile(lockPath, "utf-8");
885
1201
  const parsed = JSON.parse(content);
886
- if (typeof parsed.version !== "number" || !parsed.skills) return createEmptyLockFile();
1202
+ if (typeof parsed.version !== "number") return createEmptyLockFile();
887
1203
  if (parsed.version < CURRENT_VERSION) return createEmptyLockFile();
888
- return parsed;
1204
+ const cognitives = parsed.cognitives ?? parsed.skills ?? {};
1205
+ const migratedCognitives = {};
1206
+ for (const [name, entry] of Object.entries(cognitives)) migratedCognitives[name] = {
1207
+ source: entry.source,
1208
+ sourceType: entry.sourceType,
1209
+ sourceUrl: entry.sourceUrl,
1210
+ cognitivePath: entry.cognitivePath ?? entry.skillPath,
1211
+ cognitiveFolderHash: entry.cognitiveFolderHash ?? entry.skillFolderHash,
1212
+ installedAt: entry.installedAt,
1213
+ updatedAt: entry.updatedAt,
1214
+ cognitiveType: entry.cognitiveType
1215
+ };
1216
+ return {
1217
+ version: parsed.version,
1218
+ cognitives: migratedCognitives,
1219
+ dismissed: parsed.dismissed,
1220
+ lastSelectedAgents: parsed.lastSelectedAgents
1221
+ };
889
1222
  } catch (error) {
890
1223
  return createEmptyLockFile();
891
1224
  }
892
1225
  }
893
- async function writeSkillLock(lock) {
894
- const lockPath = getSkillLockPath$2();
1226
+ async function writeLockFile(lock) {
1227
+ const lockPath = getLockFilePath();
895
1228
  await mkdir(dirname(lockPath), { recursive: true });
896
1229
  await writeFile(lockPath, JSON.stringify(lock, null, 2), "utf-8");
897
1230
  }
@@ -911,16 +1244,21 @@ function getGitHubToken() {
911
1244
  } catch {}
912
1245
  return null;
913
1246
  }
914
- async function fetchSkillFolderHash(ownerRepo, skillPath, token) {
915
- let folderPath = skillPath.replace(/\\/g, "/");
916
- if (folderPath.endsWith("/SKILL.md")) folderPath = folderPath.slice(0, -9);
917
- else if (folderPath.endsWith("SKILL.md")) folderPath = folderPath.slice(0, -8);
1247
+ async function fetchCognitiveFolderHash(ownerRepo, cognitivePath, token) {
1248
+ let folderPath = cognitivePath.replace(/\\/g, "/");
1249
+ for (const fileName of Object.values(COGNITIVE_FILE_NAMES)) if (folderPath.endsWith("/" + fileName)) {
1250
+ folderPath = folderPath.slice(0, -(fileName.length + 1));
1251
+ break;
1252
+ } else if (folderPath.endsWith(fileName)) {
1253
+ folderPath = folderPath.slice(0, -fileName.length);
1254
+ break;
1255
+ }
918
1256
  if (folderPath.endsWith("/")) folderPath = folderPath.slice(0, -1);
919
1257
  for (const branch of ["main", "master"]) try {
920
1258
  const url = `https://api.github.com/repos/${ownerRepo}/git/trees/${branch}?recursive=1`;
921
1259
  const headers = {
922
1260
  Accept: "application/vnd.github.v3+json",
923
- "User-Agent": "skills-cli"
1261
+ "User-Agent": "synk-cli"
924
1262
  };
925
1263
  if (token) headers["Authorization"] = `Bearer ${token}`;
926
1264
  const response = await fetch(url, { headers });
@@ -935,53 +1273,50 @@ async function fetchSkillFolderHash(ownerRepo, skillPath, token) {
935
1273
  return null;
936
1274
  }
937
1275
  async function addCognitiveToLock(name, cognitiveType, entry) {
938
- const lock = await readSkillLock$2();
1276
+ const lock = await readLockFile();
939
1277
  const now = (/* @__PURE__ */ new Date()).toISOString();
940
- const existingEntry = lock.skills[name];
941
- lock.skills[name] = {
1278
+ const existingEntry = lock.cognitives[name];
1279
+ lock.cognitives[name] = {
942
1280
  ...entry,
943
1281
  cognitiveType,
944
1282
  installedAt: existingEntry?.installedAt ?? now,
945
1283
  updatedAt: now
946
1284
  };
947
- await writeSkillLock(lock);
948
- }
949
- async function addSkillToLock(skillName, entry) {
950
- return addCognitiveToLock(skillName, "skill", entry);
1285
+ await writeLockFile(lock);
951
1286
  }
952
- async function removeSkillFromLock(skillName) {
953
- const lock = await readSkillLock$2();
954
- if (!(skillName in lock.skills)) return false;
955
- delete lock.skills[skillName];
956
- await writeSkillLock(lock);
1287
+ async function removeCognitiveFromLock(name) {
1288
+ const lock = await readLockFile();
1289
+ if (!(name in lock.cognitives)) return false;
1290
+ delete lock.cognitives[name];
1291
+ await writeLockFile(lock);
957
1292
  return true;
958
1293
  }
959
- async function getSkillFromLock(skillName) {
960
- return (await readSkillLock$2()).skills[skillName] ?? null;
1294
+ async function getCognitiveFromLock(name) {
1295
+ return (await readLockFile()).cognitives[name] ?? null;
961
1296
  }
962
1297
  function createEmptyLockFile() {
963
1298
  return {
964
1299
  version: CURRENT_VERSION,
965
- skills: {},
1300
+ cognitives: {},
966
1301
  dismissed: {}
967
1302
  };
968
1303
  }
969
1304
  async function isPromptDismissed(promptKey) {
970
- return (await readSkillLock$2()).dismissed?.[promptKey] === true;
1305
+ return (await readLockFile()).dismissed?.[promptKey] === true;
971
1306
  }
972
1307
  async function dismissPrompt(promptKey) {
973
- const lock = await readSkillLock$2();
1308
+ const lock = await readLockFile();
974
1309
  if (!lock.dismissed) lock.dismissed = {};
975
1310
  lock.dismissed[promptKey] = true;
976
- await writeSkillLock(lock);
1311
+ await writeLockFile(lock);
977
1312
  }
978
1313
  async function getLastSelectedAgents() {
979
- return (await readSkillLock$2()).lastSelectedAgents;
1314
+ return (await readLockFile()).lastSelectedAgents;
980
1315
  }
981
1316
  async function saveSelectedAgents(agents) {
982
- const lock = await readSkillLock$2();
1317
+ const lock = await readLockFile();
983
1318
  lock.lastSelectedAgents = agents;
984
- await writeSkillLock(lock);
1319
+ await writeLockFile(lock);
985
1320
  }
986
1321
  const silentOutput = new Writable({ write(_chunk, _encoding, callback) {
987
1322
  callback();
@@ -1178,11 +1513,12 @@ async function promptForAgents(message, choices) {
1178
1513
  return selected;
1179
1514
  }
1180
1515
  async function selectAgentsInteractive(options) {
1181
- const supportsGlobalFilter = (a) => !options.global || agents[a].globalSkillsDir;
1516
+ const cognitiveType = options.cognitiveType ?? "skill";
1517
+ const supportsGlobalFilter = (a) => !options.global || agents[a].dirs[cognitiveType]?.global;
1182
1518
  const universalAgents = getUniversalAgents().filter(supportsGlobalFilter);
1183
1519
  const otherAgents = getNonUniversalAgents().filter(supportsGlobalFilter);
1184
1520
  const universalSection = {
1185
- title: "Universal (.agents/skills)",
1521
+ title: `Universal (.agents/${COGNITIVE_SUBDIRS[cognitiveType]})`,
1186
1522
  items: universalAgents.map((a) => ({
1187
1523
  value: a,
1188
1524
  label: agents[a].displayName
@@ -1191,7 +1527,7 @@ async function selectAgentsInteractive(options) {
1191
1527
  const otherChoices = otherAgents.map((a) => ({
1192
1528
  value: a,
1193
1529
  label: agents[a].displayName,
1194
- hint: options.global ? agents[a].globalSkillsDir : agents[a].skillsDir
1530
+ hint: options.global ? agents[a].dirs[cognitiveType].global : agents[a].dirs[cognitiveType].local
1195
1531
  }));
1196
1532
  let lastSelected;
1197
1533
  try {
@@ -1286,9 +1622,6 @@ async function parseCognitiveMd(mdPath, cognitiveType, options) {
1286
1622
  return null;
1287
1623
  }
1288
1624
  }
1289
- async function parseSkillMd(skillMdPath, options) {
1290
- return parseCognitiveMd(skillMdPath, "skill", options);
1291
- }
1292
1625
  function isContainedIn(targetPath, basePath) {
1293
1626
  const normalizedBase = normalize(resolve(basePath));
1294
1627
  const normalizedTarget = normalize(resolve(targetPath));
@@ -1331,11 +1664,7 @@ const SKIP_DIRS = [
1331
1664
  "build",
1332
1665
  "__pycache__"
1333
1666
  ];
1334
- const ALL_COGNITIVE_TYPES = [
1335
- "skill",
1336
- "agent",
1337
- "prompt"
1338
- ];
1667
+ const ALL_COGNITIVE_TYPES = Object.keys(COGNITIVE_FILE_NAMES);
1339
1668
  const AGENT_DIR_PREFIXES = [
1340
1669
  ".agent",
1341
1670
  ".agents",
@@ -1447,20 +1776,14 @@ async function discoverCognitives(basePath, subpath, options) {
1447
1776
  }
1448
1777
  return results;
1449
1778
  }
1450
- async function discoverSkills(basePath, subpath, options) {
1451
- return discoverCognitives(basePath, subpath, {
1452
- ...options,
1453
- types: options?.types ?? ["skill"]
1454
- });
1455
- }
1456
- function getSkillDisplayName(skill) {
1457
- return skill.name || basename(skill.path);
1779
+ function getCognitiveDisplayName(cognitive) {
1780
+ return cognitive.name || basename(cognitive.path);
1458
1781
  }
1459
- function filterSkills(skills, inputNames) {
1782
+ function filterCognitives(cognitives, inputNames) {
1460
1783
  const normalizedInputs = inputNames.map((n) => n.toLowerCase());
1461
- return skills.filter((skill) => {
1462
- const name = skill.name.toLowerCase();
1463
- const displayName = getSkillDisplayName(skill).toLowerCase();
1784
+ return cognitives.filter((cognitive) => {
1785
+ const name = cognitive.name.toLowerCase();
1786
+ const displayName = getCognitiveDisplayName(cognitive).toLowerCase();
1464
1787
  return normalizedInputs.some((input) => input === name || input === displayName);
1465
1788
  });
1466
1789
  }
@@ -1473,7 +1796,7 @@ function isPathSafe(basePath, targetPath) {
1473
1796
  return normalizedTarget.startsWith(normalizedBase + sep) || normalizedTarget === normalizedBase;
1474
1797
  }
1475
1798
  function getCanonicalDir(cognitiveType, global, cwd) {
1476
- return join(global ? homedir() : cwd || process.cwd(), AGENTS_DIR$3, COGNITIVE_SUBDIRS[cognitiveType]);
1799
+ return join(global ? homedir() : cwd || process.cwd(), AGENTS_DIR$1, COGNITIVE_SUBDIRS[cognitiveType]);
1477
1800
  }
1478
1801
  function getInstallPath(skillName, agentType, options = {}) {
1479
1802
  const cognitiveType = options.cognitiveType ?? "skill";
@@ -1636,7 +1959,7 @@ async function installCognitiveForAgent(cognitive, agentType, options = {}) {
1636
1959
  };
1637
1960
  }
1638
1961
  }
1639
- async function installRemoteSkillForAgent(skill, agentType, options = {}) {
1962
+ async function installRemoteCognitiveForAgent(skill, agentType, options = {}) {
1640
1963
  const cognitiveType = options.cognitiveType ?? skill.cognitiveType ?? "skill";
1641
1964
  const agent = agents[agentType];
1642
1965
  const isGlobal = options.global ?? false;
@@ -1650,12 +1973,12 @@ async function installRemoteSkillForAgent(skill, agentType, options = {}) {
1650
1973
  mode: installMode,
1651
1974
  error: `${agent.displayName} does not support global ${cognitiveType} installation`
1652
1975
  };
1653
- const skillName = sanitizeName(skill.installName);
1976
+ const cognitiveName = sanitizeName(skill.installName);
1654
1977
  const canonicalBase = getCanonicalDir(cognitiveType, isGlobal, cwd);
1655
- const canonicalDir = join(canonicalBase, skillName);
1978
+ const canonicalDir = join(canonicalBase, cognitiveName);
1656
1979
  const localDir = getCognitiveDir(agentType, cognitiveType, "local");
1657
1980
  const agentBase = isGlobal ? globalDir : join(cwd, localDir);
1658
- const agentDir = join(agentBase, skillName);
1981
+ const agentDir = join(agentBase, cognitiveName);
1659
1982
  if (!isPathSafe(canonicalBase, canonicalDir)) return {
1660
1983
  success: false,
1661
1984
  path: agentDir,
@@ -1712,7 +2035,7 @@ async function installRemoteSkillForAgent(skill, agentType, options = {}) {
1712
2035
  };
1713
2036
  }
1714
2037
  }
1715
- async function installWellKnownSkillForAgent(skill, agentType, options = {}) {
2038
+ async function installWellKnownCognitiveForAgent(skill, agentType, options = {}) {
1716
2039
  const cognitiveType = options.cognitiveType ?? "skill";
1717
2040
  const agent = agents[agentType];
1718
2041
  const isGlobal = options.global ?? false;
@@ -1725,12 +2048,12 @@ async function installWellKnownSkillForAgent(skill, agentType, options = {}) {
1725
2048
  mode: installMode,
1726
2049
  error: `${agent.displayName} does not support global ${cognitiveType} installation`
1727
2050
  };
1728
- const skillName = sanitizeName(skill.installName);
2051
+ const cognitiveName = sanitizeName(skill.installName);
1729
2052
  const canonicalBase = getCanonicalDir(cognitiveType, isGlobal, cwd);
1730
- const canonicalDir = join(canonicalBase, skillName);
2053
+ const canonicalDir = join(canonicalBase, cognitiveName);
1731
2054
  const localDir = getCognitiveDir(agentType, cognitiveType, "local");
1732
2055
  const agentBase = isGlobal ? globalDir : join(cwd, localDir);
1733
- const agentDir = join(agentBase, skillName);
2056
+ const agentDir = join(agentBase, cognitiveName);
1734
2057
  if (!isPathSafe(canonicalBase, canonicalDir)) return {
1735
2058
  success: false,
1736
2059
  path: agentDir,
@@ -1798,11 +2121,7 @@ async function installWellKnownSkillForAgent(skill, agentType, options = {}) {
1798
2121
  }
1799
2122
  async function listInstalledCognitives(options = {}) {
1800
2123
  const cwd = options.cwd || process.cwd();
1801
- const typesToScan = options.typeFilter ?? [
1802
- "skill",
1803
- "agent",
1804
- "prompt"
1805
- ];
2124
+ const typesToScan = options.typeFilter ?? Object.keys(COGNITIVE_FILE_NAMES);
1806
2125
  const cognitivesMap = /* @__PURE__ */ new Map();
1807
2126
  const detectedAgents = await detectInstalledAgents();
1808
2127
  const agentFilter = options.agentFilter;
@@ -1841,7 +2160,7 @@ async function listInstalledCognitives(options = {}) {
1841
2160
  } catch {
1842
2161
  continue;
1843
2162
  }
1844
- const parsed = cognitiveType === "skill" ? await parseSkillMd(mdPath) : await parseCognitiveMd(mdPath, cognitiveType);
2163
+ const parsed = await parseCognitiveMd(mdPath, cognitiveType);
1845
2164
  if (!parsed) continue;
1846
2165
  const scopeKey = scope.global ? "global" : "project";
1847
2166
  const cognitiveKey = `${scopeKey}:${cognitiveType}:${parsed.name}`;
@@ -1891,7 +2210,7 @@ async function listInstalledCognitives(options = {}) {
1891
2210
  try {
1892
2211
  const candidateMdPath = join(candidateDir, fileName);
1893
2212
  await stat(candidateMdPath);
1894
- const candidateParsed = cognitiveType === "skill" ? await parseSkillMd(candidateMdPath) : await parseCognitiveMd(candidateMdPath, cognitiveType);
2213
+ const candidateParsed = await parseCognitiveMd(candidateMdPath, cognitiveType);
1895
2214
  if (candidateParsed && candidateParsed.name === parsed.name) {
1896
2215
  found = true;
1897
2216
  break;
@@ -1918,12 +2237,6 @@ async function listInstalledCognitives(options = {}) {
1918
2237
  }
1919
2238
  return Array.from(cognitivesMap.values());
1920
2239
  }
1921
- async function listInstalledSkills(options = {}) {
1922
- return listInstalledCognitives({
1923
- ...options,
1924
- typeFilter: ["skill"]
1925
- });
1926
- }
1927
2240
  async function isCognitiveInstalled(name, agentType, cognitiveType, options = {}) {
1928
2241
  const sanitized = sanitizeName(name);
1929
2242
  const globalDir = getCognitiveDir(agentType, cognitiveType, "global");
@@ -1939,9 +2252,6 @@ async function isCognitiveInstalled(name, agentType, cognitiveType, options = {}
1939
2252
  return false;
1940
2253
  }
1941
2254
  }
1942
- async function isSkillInstalled(skillName, agentType, options = {}) {
1943
- return isCognitiveInstalled(skillName, agentType, options.cognitiveType ?? "skill", options);
1944
- }
1945
2255
  const TELEMETRY_URL = "https://add-skill.vercel.sh/t";
1946
2256
  let cliVersion = null;
1947
2257
  function isCI() {
@@ -1984,17 +2294,28 @@ function registerProvider(provider) {
1984
2294
  function findProvider(url) {
1985
2295
  return registry.findProvider(url);
1986
2296
  }
2297
+ const FILE_NAME_TO_TYPE$1 = new Map(Object.entries(COGNITIVE_FILE_NAMES).map(([type, name]) => [name.toLowerCase(), type]));
2298
+ function detectCognitiveType$1(url) {
2299
+ const lower = url.toLowerCase();
2300
+ for (const [fileName, type] of FILE_NAME_TO_TYPE$1) if (lower.endsWith("/" + fileName)) return type;
2301
+ return "skill";
2302
+ }
2303
+ function matchesCognitiveFile$1(url) {
2304
+ const lower = url.toLowerCase();
2305
+ for (const fileName of FILE_NAME_TO_TYPE$1.keys()) if (lower.endsWith("/" + fileName)) return true;
2306
+ return false;
2307
+ }
1987
2308
  var MintlifyProvider = class {
1988
2309
  id = "mintlify";
1989
2310
  displayName = "Mintlify";
1990
2311
  match(url) {
1991
2312
  if (!url.startsWith("http://") && !url.startsWith("https://")) return { matches: false };
1992
- if (!url.toLowerCase().endsWith("/skill.md")) return { matches: false };
2313
+ if (!matchesCognitiveFile$1(url)) return { matches: false };
1993
2314
  if (url.includes("github.com") || url.includes("gitlab.com")) return { matches: false };
1994
2315
  if (url.includes("huggingface.co")) return { matches: false };
1995
2316
  return { matches: true };
1996
2317
  }
1997
- async fetchSkill(url) {
2318
+ async fetchCognitive(url) {
1998
2319
  try {
1999
2320
  const response = await fetch(url, { signal: AbortSignal.timeout(3e4) });
2000
2321
  if (!response.ok) return null;
@@ -2009,12 +2330,16 @@ var MintlifyProvider = class {
2009
2330
  content,
2010
2331
  installName: mintlifySite,
2011
2332
  sourceUrl: url,
2012
- metadata: data.metadata
2333
+ metadata: data.metadata,
2334
+ cognitiveType: detectCognitiveType$1(url)
2013
2335
  };
2014
2336
  } catch {
2015
2337
  return null;
2016
2338
  }
2017
2339
  }
2340
+ async fetchSkill(url) {
2341
+ return this.fetchCognitive(url);
2342
+ }
2018
2343
  toRawUrl(url) {
2019
2344
  return url;
2020
2345
  }
@@ -2023,6 +2348,17 @@ var MintlifyProvider = class {
2023
2348
  }
2024
2349
  };
2025
2350
  const mintlifyProvider = new MintlifyProvider();
2351
+ const FILE_NAME_TO_TYPE = new Map(Object.entries(COGNITIVE_FILE_NAMES).map(([type, name]) => [name.toLowerCase(), type]));
2352
+ function matchesCognitiveFile(url) {
2353
+ const lower = url.toLowerCase();
2354
+ for (const fileName of FILE_NAME_TO_TYPE.keys()) if (lower.endsWith("/" + fileName)) return true;
2355
+ return false;
2356
+ }
2357
+ function detectCognitiveType(url) {
2358
+ const lower = url.toLowerCase();
2359
+ for (const [fileName, type] of FILE_NAME_TO_TYPE) if (lower.endsWith("/" + fileName)) return type;
2360
+ return "skill";
2361
+ }
2026
2362
  var HuggingFaceProvider = class {
2027
2363
  id = "huggingface";
2028
2364
  displayName = "HuggingFace";
@@ -2034,11 +2370,11 @@ var HuggingFaceProvider = class {
2034
2370
  } catch {
2035
2371
  return { matches: false };
2036
2372
  }
2037
- if (!url.toLowerCase().endsWith("/skill.md")) return { matches: false };
2373
+ if (!matchesCognitiveFile(url)) return { matches: false };
2038
2374
  if (!url.includes("/spaces/")) return { matches: false };
2039
2375
  return { matches: true };
2040
2376
  }
2041
- async fetchSkill(url) {
2377
+ async fetchCognitive(url) {
2042
2378
  try {
2043
2379
  const rawUrl = this.toRawUrl(url);
2044
2380
  const response = await fetch(rawUrl, { signal: AbortSignal.timeout(3e4) });
@@ -2055,7 +2391,8 @@ var HuggingFaceProvider = class {
2055
2391
  content,
2056
2392
  installName,
2057
2393
  sourceUrl: url,
2058
- metadata: data.metadata
2394
+ metadata: data.metadata,
2395
+ cognitiveType: detectCognitiveType(url)
2059
2396
  };
2060
2397
  } catch {
2061
2398
  return null;
@@ -2069,6 +2406,9 @@ var HuggingFaceProvider = class {
2069
2406
  if (!parsed) return "huggingface/unknown";
2070
2407
  return `huggingface/${parsed.owner}/${parsed.repo}`;
2071
2408
  }
2409
+ async fetchSkill(url) {
2410
+ return this.fetchCognitive(url);
2411
+ }
2072
2412
  parseUrl(url) {
2073
2413
  const match = url.match(/\/spaces\/([^/]+)\/([^/]+)/);
2074
2414
  if (!match || !match[1] || !match[2]) return null;
@@ -2081,8 +2421,9 @@ var HuggingFaceProvider = class {
2081
2421
  const huggingFaceProvider = new HuggingFaceProvider();
2082
2422
  var WellKnownProvider = class {
2083
2423
  id = "well-known";
2084
- displayName = "Well-Known Skills";
2085
- WELL_KNOWN_PATH = ".well-known/skills";
2424
+ displayName = "Well-Known Cognitives";
2425
+ WELL_KNOWN_PATH = ".well-known/cognitives";
2426
+ WELL_KNOWN_PATH_LEGACY = ".well-known/skills";
2086
2427
  INDEX_FILE = "index.json";
2087
2428
  match(url) {
2088
2429
  if (!url.startsWith("http://") && !url.startsWith("https://")) return { matches: false };
@@ -2105,37 +2446,41 @@ var WellKnownProvider = class {
2105
2446
  try {
2106
2447
  const parsed = new URL(baseUrl);
2107
2448
  const basePath = parsed.pathname.replace(/\/$/, "");
2108
- const urlsToTry = [{
2109
- indexUrl: `${parsed.protocol}//${parsed.host}${basePath}/${this.WELL_KNOWN_PATH}/${this.INDEX_FILE}`,
2110
- baseUrl: `${parsed.protocol}//${parsed.host}${basePath}`
2111
- }];
2112
- if (basePath && basePath !== "") urlsToTry.push({
2113
- indexUrl: `${parsed.protocol}//${parsed.host}/${this.WELL_KNOWN_PATH}/${this.INDEX_FILE}`,
2114
- baseUrl: `${parsed.protocol}//${parsed.host}`
2115
- });
2116
- for (const { indexUrl, baseUrl: resolvedBase } of urlsToTry) try {
2117
- const response = await fetch(indexUrl);
2118
- if (!response.ok) continue;
2119
- const index = await response.json();
2120
- if (!index.skills || !Array.isArray(index.skills)) continue;
2121
- let allValid = true;
2122
- for (const entry of index.skills) if (!this.isValidSkillEntry(entry)) {
2123
- allValid = false;
2124
- break;
2449
+ const wellKnownPaths = [this.WELL_KNOWN_PATH, this.WELL_KNOWN_PATH_LEGACY];
2450
+ for (const wkPath of wellKnownPaths) {
2451
+ const urlsToTry = [{
2452
+ indexUrl: `${parsed.protocol}//${parsed.host}${basePath}/${wkPath}/${this.INDEX_FILE}`,
2453
+ baseUrl: `${parsed.protocol}//${parsed.host}${basePath}`
2454
+ }];
2455
+ if (basePath && basePath !== "") urlsToTry.push({
2456
+ indexUrl: `${parsed.protocol}//${parsed.host}/${wkPath}/${this.INDEX_FILE}`,
2457
+ baseUrl: `${parsed.protocol}//${parsed.host}`
2458
+ });
2459
+ for (const { indexUrl, baseUrl: resolvedBase } of urlsToTry) try {
2460
+ const response = await fetch(indexUrl);
2461
+ if (!response.ok) continue;
2462
+ const raw = await response.json();
2463
+ const entries = raw.cognitives ?? raw.skills;
2464
+ if (!entries || !Array.isArray(entries)) continue;
2465
+ let allValid = true;
2466
+ for (const entry of entries) if (!this.isValidCognitiveEntry(entry)) {
2467
+ allValid = false;
2468
+ break;
2469
+ }
2470
+ if (allValid) return {
2471
+ index: { cognitives: entries },
2472
+ resolvedBaseUrl: resolvedBase
2473
+ };
2474
+ } catch {
2475
+ continue;
2125
2476
  }
2126
- if (allValid) return {
2127
- index,
2128
- resolvedBaseUrl: resolvedBase
2129
- };
2130
- } catch {
2131
- continue;
2132
2477
  }
2133
2478
  return null;
2134
2479
  } catch {
2135
2480
  return null;
2136
2481
  }
2137
2482
  }
2138
- isValidSkillEntry(entry) {
2483
+ isValidCognitiveEntry(entry) {
2139
2484
  if (!entry || typeof entry !== "object") return false;
2140
2485
  const e = entry;
2141
2486
  if (typeof e.name !== "string" || !e.name) return false;
@@ -2148,41 +2493,50 @@ var WellKnownProvider = class {
2148
2493
  if (typeof file !== "string") return false;
2149
2494
  if (file.startsWith("/") || file.startsWith("\\") || file.includes("..")) return false;
2150
2495
  }
2151
- if (!e.files.some((f) => typeof f === "string" && f.toLowerCase() === "skill.md")) return false;
2496
+ const cognitiveFileNames = new Set(Object.values(COGNITIVE_FILE_NAMES).map((n) => n.toLowerCase()));
2497
+ if (!e.files.some((f) => typeof f === "string" && cognitiveFileNames.has(f.toLowerCase()))) return false;
2152
2498
  return true;
2153
2499
  }
2154
- async fetchSkill(url) {
2500
+ async fetchCognitive(url) {
2155
2501
  try {
2156
2502
  const parsed = new URL(url);
2157
2503
  const result = await this.fetchIndex(url);
2158
2504
  if (!result) return null;
2159
2505
  const { index, resolvedBaseUrl } = result;
2160
- let skillName = null;
2161
- const pathMatch = parsed.pathname.match(/\/.well-known\/skills\/([^/]+)\/?$/);
2162
- if (pathMatch && pathMatch[1] && pathMatch[1] !== "index.json") skillName = pathMatch[1];
2163
- else if (index.skills.length === 1) skillName = index.skills[0].name;
2164
- if (!skillName) return null;
2165
- const skillEntry = index.skills.find((s) => s.name === skillName);
2166
- if (!skillEntry) return null;
2167
- return this.fetchSkillByEntry(resolvedBaseUrl, skillEntry);
2506
+ let cognitiveName = null;
2507
+ const pathMatch = parsed.pathname.match(/\/.well-known\/cognitives\/([^/]+)\/?$/) ?? parsed.pathname.match(/\/.well-known\/skills\/([^/]+)\/?$/);
2508
+ if (pathMatch && pathMatch[1] && pathMatch[1] !== "index.json") cognitiveName = pathMatch[1];
2509
+ else if (index.cognitives.length === 1) cognitiveName = index.cognitives[0].name;
2510
+ if (!cognitiveName) return null;
2511
+ const cognitiveEntry = index.cognitives.find((s) => s.name === cognitiveName);
2512
+ if (!cognitiveEntry) return null;
2513
+ return this.fetchCognitiveByEntry(resolvedBaseUrl, cognitiveEntry);
2168
2514
  } catch {
2169
2515
  return null;
2170
2516
  }
2171
2517
  }
2172
- async fetchSkillByEntry(baseUrl, entry) {
2518
+ async fetchCognitiveByEntry(baseUrl, entry) {
2173
2519
  try {
2174
- const skillBaseUrl = `${baseUrl.replace(/\/$/, "")}/${this.WELL_KNOWN_PATH}/${entry.name}`;
2175
- const skillMdUrl = `${skillBaseUrl}/SKILL.md`;
2176
- const response = await fetch(skillMdUrl);
2520
+ const cognitiveBaseUrl = `${baseUrl.replace(/\/$/, "")}/${this.WELL_KNOWN_PATH}/${entry.name}`;
2521
+ const cognitiveFileNames = Object.values(COGNITIVE_FILE_NAMES).map((n) => n.toLowerCase());
2522
+ const primaryFile = entry.files.find((f) => cognitiveFileNames.includes(f.toLowerCase()));
2523
+ if (!primaryFile) return null;
2524
+ const cognitiveType = Object.entries(COGNITIVE_FILE_NAMES).find(([_, name]) => name.toLowerCase() === primaryFile.toLowerCase())?.[0] ?? "skill";
2525
+ const primaryUrl = `${cognitiveBaseUrl}/${primaryFile}`;
2526
+ let response = await fetch(primaryUrl);
2527
+ if (!response.ok) {
2528
+ const legacyPrimaryUrl = `${`${baseUrl.replace(/\/$/, "")}/${this.WELL_KNOWN_PATH_LEGACY}/${entry.name}`}/${primaryFile}`;
2529
+ response = await fetch(legacyPrimaryUrl);
2530
+ }
2177
2531
  if (!response.ok) return null;
2178
2532
  const content = await response.text();
2179
2533
  const { data } = (0, import_gray_matter.default)(content);
2180
2534
  if (!data.name || !data.description) return null;
2181
2535
  const files = /* @__PURE__ */ new Map();
2182
- files.set("SKILL.md", content);
2183
- const filePromises = entry.files.filter((f) => f.toLowerCase() !== "skill.md").map(async (filePath) => {
2536
+ files.set(primaryFile, content);
2537
+ const filePromises = entry.files.filter((f) => f.toLowerCase() !== primaryFile.toLowerCase()).map(async (filePath) => {
2184
2538
  try {
2185
- const fileUrl = `${skillBaseUrl}/${filePath}`;
2539
+ const fileUrl = `${cognitiveBaseUrl}/${filePath}`;
2186
2540
  const fileResponse = await fetch(fileUrl);
2187
2541
  if (fileResponse.ok) return {
2188
2542
  path: filePath,
@@ -2198,8 +2552,9 @@ var WellKnownProvider = class {
2198
2552
  description: data.description,
2199
2553
  content,
2200
2554
  installName: entry.name,
2201
- sourceUrl: skillMdUrl,
2555
+ sourceUrl: primaryUrl,
2202
2556
  metadata: data.metadata,
2557
+ cognitiveType,
2203
2558
  files,
2204
2559
  indexEntry: entry
2205
2560
  };
@@ -2207,13 +2562,13 @@ var WellKnownProvider = class {
2207
2562
  return null;
2208
2563
  }
2209
2564
  }
2210
- async fetchAllSkills(url) {
2565
+ async fetchAllCognitives(url) {
2211
2566
  try {
2212
2567
  const result = await this.fetchIndex(url);
2213
2568
  if (!result) return [];
2214
2569
  const { index, resolvedBaseUrl } = result;
2215
- const skillPromises = index.skills.map((entry) => this.fetchSkillByEntry(resolvedBaseUrl, entry));
2216
- return (await Promise.all(skillPromises)).filter((s) => s !== null);
2570
+ const cognitivePromises = index.cognitives.map((entry) => this.fetchCognitiveByEntry(resolvedBaseUrl, entry));
2571
+ return (await Promise.all(cognitivePromises)).filter((s) => s !== null);
2217
2572
  } catch {
2218
2573
  return [];
2219
2574
  }
@@ -2221,11 +2576,16 @@ var WellKnownProvider = class {
2221
2576
  toRawUrl(url) {
2222
2577
  try {
2223
2578
  const parsed = new URL(url);
2224
- if (url.toLowerCase().endsWith("/skill.md")) return url;
2225
- const pathMatch = parsed.pathname.match(/\/.well-known\/skills\/([^/]+)\/?$/);
2579
+ const cognitiveFileNames = Object.values(COGNITIVE_FILE_NAMES).map((n) => n.toLowerCase());
2580
+ const lower = url.toLowerCase();
2581
+ if (cognitiveFileNames.some((f) => lower.endsWith("/" + f))) return url;
2582
+ const pathMatch = parsed.pathname.match(/\/.well-known\/cognitives\/([^/]+?)(?:\/([^/]+))?\/?$/) ?? parsed.pathname.match(/\/.well-known\/skills\/([^/]+?)(?:\/([^/]+))?\/?$/);
2226
2583
  if (pathMatch && pathMatch[1]) {
2227
- const basePath = parsed.pathname.replace(/\/.well-known\/skills\/.*$/, "");
2228
- return `${parsed.protocol}//${parsed.host}${basePath}/${this.WELL_KNOWN_PATH}/${pathMatch[1]}/SKILL.md`;
2584
+ const matchedWkPath = parsed.pathname.includes(".well-known/cognitives") ? this.WELL_KNOWN_PATH : this.WELL_KNOWN_PATH_LEGACY;
2585
+ const basePath = parsed.pathname.replace(/\/.well-known\/(?:cognitives|skills)\/.*$/, "");
2586
+ const trailingFile = pathMatch[2]?.toLowerCase();
2587
+ const cognitiveFile = cognitiveFileNames.find((f) => f === trailingFile) ? pathMatch[2] : COGNITIVE_FILE_NAMES.skill;
2588
+ return `${parsed.protocol}//${parsed.host}${basePath}/${matchedWkPath}/${pathMatch[1]}/${cognitiveFile}`;
2229
2589
  }
2230
2590
  const basePath = parsed.pathname.replace(/\/$/, "");
2231
2591
  return `${parsed.protocol}//${parsed.host}${basePath}/${this.WELL_KNOWN_PATH}/${this.INDEX_FILE}`;
@@ -2246,34 +2606,50 @@ var WellKnownProvider = class {
2246
2606
  return "unknown/unknown";
2247
2607
  }
2248
2608
  }
2249
- async hasSkillsIndex(url) {
2609
+ async hasCognitivesIndex(url) {
2250
2610
  return await this.fetchIndex(url) !== null;
2251
2611
  }
2612
+ async hasSkillsIndex(url) {
2613
+ return this.hasCognitivesIndex(url);
2614
+ }
2615
+ async fetchSkill(url) {
2616
+ return this.fetchCognitive(url);
2617
+ }
2618
+ async fetchSkillByEntry(baseUrl, entry) {
2619
+ return this.fetchCognitiveByEntry(baseUrl, entry);
2620
+ }
2621
+ async fetchAllSkills(url) {
2622
+ return this.fetchAllCognitives(url);
2623
+ }
2252
2624
  };
2253
2625
  const wellKnownProvider = new WellKnownProvider();
2254
2626
  registerProvider(mintlifyProvider);
2255
2627
  registerProvider(huggingFaceProvider);
2256
- async function fetchMintlifySkill(url) {
2257
- try {
2258
- const response = await fetch(url, { signal: AbortSignal.timeout(3e4) });
2259
- if (!response.ok) return null;
2260
- const content = await response.text();
2261
- const { data } = (0, import_gray_matter.default)(content);
2262
- const mintlifySite = data.metadata?.["mintlify-proj"];
2263
- if (!mintlifySite) return null;
2264
- if (!data.name || !data.description) return null;
2265
- return {
2266
- name: data.name,
2267
- description: data.description,
2268
- content,
2269
- mintlifySite,
2270
- sourceUrl: url
2271
- };
2272
- } catch {
2273
- return null;
2628
+ var version$1 = "1.1.0";
2629
+ function assertNotCancelled(value, cleanup) {
2630
+ if (pD(value)) {
2631
+ logger.cancel("Operation cancelled");
2632
+ if (cleanup) cleanup().then(() => process.exit(0)).catch(() => process.exit(0));
2633
+ else process.exit(0);
2634
+ throw new Error("cancelled");
2635
+ }
2636
+ }
2637
+ function validateAgentNames(agentNames) {
2638
+ const validAgents = Object.keys(agents);
2639
+ const invalid = agentNames.filter((a) => !validAgents.includes(a));
2640
+ if (invalid.length > 0) {
2641
+ logger.error(`Invalid agents: ${invalid.join(", ")}`);
2642
+ logger.info(`Valid agents: ${validAgents.join(", ")}`);
2643
+ process.exit(1);
2274
2644
  }
2645
+ return agentNames;
2646
+ }
2647
+ function buildLockEntry(params) {
2648
+ return {
2649
+ ...params,
2650
+ cognitiveFolderHash: ""
2651
+ };
2275
2652
  }
2276
- var version$1 = "1.0.0";
2277
2653
  function initTelemetry(version) {
2278
2654
  setVersion(version);
2279
2655
  }
@@ -2313,29 +2689,21 @@ async function selectTargetAgents(options, spinner, cleanup, useUniversalAgents
2313
2689
  }
2314
2690
  if (useUniversalAgents) {
2315
2691
  const selected = await selectAgentsInteractive({ global: options.global });
2316
- if (pD(selected)) {
2317
- logger.cancel("Installation cancelled");
2318
- await cleanup?.();
2319
- process.exit(0);
2320
- }
2692
+ assertNotCancelled(selected, cleanup);
2321
2693
  return selected;
2322
2694
  }
2323
- logger.info("Select agents to install skills to");
2695
+ logger.info("Select agents to install to");
2324
2696
  const selected = await promptForAgents("Which agents do you want to install to?", Object.entries(agents).map(([key, config]) => ({
2325
2697
  value: key,
2326
2698
  label: config.displayName
2327
2699
  })));
2328
- if (pD(selected)) {
2329
- logger.cancel("Installation cancelled");
2330
- await cleanup?.();
2331
- process.exit(0);
2332
- }
2700
+ assertNotCancelled(selected, cleanup);
2333
2701
  return selected;
2334
2702
  }
2335
2703
  if (installedAgents.length === 1 || options.yes) {
2336
2704
  if (useUniversalAgents) {
2337
2705
  const target = ensureUniversalAgents(installedAgents);
2338
- const { universal, symlinked } = splitAgentsByType(target);
2706
+ const { symlinked } = splitAgentsByType(target);
2339
2707
  if (symlinked.length > 0) logger.info(`Installing to: ${import_picocolors.default.green("universal")} + ${symlinked.map((a) => import_picocolors.default.cyan(a)).join(", ")}`);
2340
2708
  else logger.info(`Installing to: ${import_picocolors.default.green("universal agents")}`);
2341
2709
  return target;
@@ -2347,16 +2715,13 @@ async function selectTargetAgents(options, spinner, cleanup, useUniversalAgents
2347
2715
  return installedAgents;
2348
2716
  }
2349
2717
  const selected = await selectAgentsInteractive({ global: options.global });
2350
- if (pD(selected)) {
2351
- logger.cancel("Installation cancelled");
2352
- await cleanup?.();
2353
- process.exit(0);
2354
- }
2718
+ assertNotCancelled(selected, cleanup);
2355
2719
  return selected;
2356
2720
  }
2357
2721
  async function selectInstallScope(options, targetAgents, cleanup) {
2358
2722
  let installGlobally = options.global ?? false;
2359
- const supportsGlobal = targetAgents.some((a) => agents[a].globalSkillsDir !== void 0);
2723
+ const cogType = options.type ?? "skill";
2724
+ const supportsGlobal = targetAgents.some((a) => agents[a].dirs[cogType]?.global !== void 0);
2360
2725
  if (options.global === void 0 && !options.yes && supportsGlobal) {
2361
2726
  const scope = await ve({
2362
2727
  message: "Installation scope",
@@ -2370,11 +2735,7 @@ async function selectInstallScope(options, targetAgents, cleanup) {
2370
2735
  hint: "Install in home directory (available across all projects)"
2371
2736
  }]
2372
2737
  });
2373
- if (pD(scope)) {
2374
- logger.cancel("Installation cancelled");
2375
- await cleanup?.();
2376
- process.exit(0);
2377
- }
2738
+ assertNotCancelled(scope, cleanup);
2378
2739
  installGlobally = scope;
2379
2740
  }
2380
2741
  return installGlobally;
@@ -2393,56 +2754,53 @@ async function selectInstallMode(options, cleanup) {
2393
2754
  hint: "Independent copies for each agent"
2394
2755
  }]
2395
2756
  });
2396
- if (pD(modeChoice)) {
2397
- logger.cancel("Installation cancelled");
2398
- await cleanup?.();
2399
- process.exit(0);
2400
- }
2757
+ assertNotCancelled(modeChoice, cleanup);
2401
2758
  return modeChoice;
2402
2759
  }
2760
+ async function selectInstallContext(options, spinner, cleanup, config) {
2761
+ const targetAgents = await selectTargetAgents(options, spinner, cleanup, config?.useUniversalAgents);
2762
+ return {
2763
+ targetAgents,
2764
+ installGlobally: await selectInstallScope(options, targetAgents, cleanup),
2765
+ installMode: config?.forceMode ?? await selectInstallMode(options, cleanup)
2766
+ };
2767
+ }
2403
2768
  async function isSourcePrivate(source) {
2404
2769
  const ownerRepo = parseOwnerRepo(source);
2405
2770
  if (!ownerRepo) return false;
2406
2771
  return isRepoPrivate(ownerRepo.owner, ownerRepo.repo);
2407
2772
  }
2408
- async function executeInstallFlow(prepared, options, spinner, cleanup) {
2409
- const { items, targetAgents, installGlobally, installMode, cognitiveType } = prepared;
2410
- const cwd = process.cwd();
2773
+ async function checkOverwrites(items, targetAgents, installGlobally, cognitiveType) {
2411
2774
  const overwriteChecks = await Promise.all(items.flatMap((item) => targetAgents.map(async (agent) => ({
2412
- skillName: item.installName,
2775
+ itemName: item.installName,
2413
2776
  agent,
2414
- installed: cognitiveType === "skill" ? await isSkillInstalled(item.installName, agent, { global: installGlobally }) : await isCognitiveInstalled(item.installName, agent, cognitiveType, { global: installGlobally })
2777
+ installed: await isCognitiveInstalled(item.installName, agent, cognitiveType, { global: installGlobally })
2415
2778
  }))));
2416
2779
  const overwriteStatus = /* @__PURE__ */ new Map();
2417
- for (const { skillName, agent, installed } of overwriteChecks) {
2418
- if (!overwriteStatus.has(skillName)) overwriteStatus.set(skillName, /* @__PURE__ */ new Map());
2419
- overwriteStatus.get(skillName).set(agent, installed);
2780
+ for (const { itemName, agent, installed } of overwriteChecks) {
2781
+ if (!overwriteStatus.has(itemName)) overwriteStatus.set(itemName, /* @__PURE__ */ new Map());
2782
+ overwriteStatus.get(itemName).set(agent, installed);
2420
2783
  }
2784
+ return overwriteStatus;
2785
+ }
2786
+ function buildInstallSummary(items, targetAgents, installGlobally, installMode, cognitiveType, overwriteStatus, cwd) {
2421
2787
  const summaryLines = [];
2422
2788
  for (const item of items) {
2423
2789
  if (summaryLines.length > 0) summaryLines.push("");
2424
- const shortCanonical = shortenPath$1(getCanonicalPath(item.installName, {
2790
+ const shortCanonical = shortenPath(getCanonicalPath(item.installName, {
2425
2791
  global: installGlobally,
2426
2792
  cognitiveType
2427
2793
  }), cwd);
2428
2794
  summaryLines.push(`${import_picocolors.default.cyan(shortCanonical)}`);
2429
2795
  summaryLines.push(...buildAgentSummaryLines(targetAgents, installMode));
2430
2796
  if (item.fileCount && item.fileCount > 1) summaryLines.push(` ${import_picocolors.default.dim("files:")} ${item.fileCount}`);
2431
- const skillOverwrites = overwriteStatus.get(item.installName);
2432
- const overwriteAgents = targetAgents.filter((a) => skillOverwrites?.get(a)).map((a) => agents[a].displayName);
2433
- if (overwriteAgents.length > 0) summaryLines.push(` ${import_picocolors.default.yellow("overwrites:")} ${formatList$1(overwriteAgents)}`);
2797
+ const itemOverwrites = overwriteStatus.get(item.installName);
2798
+ const overwriteAgents = targetAgents.filter((a) => itemOverwrites?.get(a)).map((a) => agents[a].displayName);
2799
+ if (overwriteAgents.length > 0) summaryLines.push(` ${import_picocolors.default.yellow("overwrites:")} ${formatList(overwriteAgents)}`);
2434
2800
  }
2435
- logger.note(summaryLines.join("\n"), "Installation Summary");
2436
- if (!options.yes) {
2437
- const confirmed = await ye({ message: "Proceed with installation?" });
2438
- if (pD(confirmed) || !confirmed) {
2439
- logger.cancel("Installation cancelled");
2440
- await cleanup?.();
2441
- process.exit(0);
2442
- }
2443
- }
2444
- const label = items.length === 1 ? "Installing skill..." : "Installing skills...";
2445
- spinner.start(label);
2801
+ return summaryLines;
2802
+ }
2803
+ async function performInstalls(items, targetAgents, installGlobally, installMode) {
2446
2804
  const results = [];
2447
2805
  for (const item of items) for (const agent of targetAgents) {
2448
2806
  const result = await item.installFn(agent, {
@@ -2450,450 +2808,383 @@ async function executeInstallFlow(prepared, options, spinner, cleanup) {
2450
2808
  mode: installMode
2451
2809
  });
2452
2810
  results.push({
2453
- skill: item.installName,
2811
+ name: item.installName,
2454
2812
  agent: agents[agent].displayName,
2455
2813
  ...result
2456
2814
  });
2457
2815
  }
2458
- spinner.succeed("Installation complete");
2459
- logger.line();
2460
- const successful = results.filter((r) => r.success);
2461
- const failed = results.filter((r) => !r.success);
2462
- const { telemetry } = prepared;
2463
- if (telemetry.source) {
2464
- let shouldTrack = true;
2465
- if (telemetry.checkPrivacy) {
2466
- if (await isSourcePrivate(telemetry.source) === true) shouldTrack = false;
2816
+ return results;
2817
+ }
2818
+ async function writeLockEntries(prepared, successfulNames) {
2819
+ for (const entry of prepared.lockEntries) if (successfulNames.has(entry.name)) try {
2820
+ let cognitiveFolderHash = entry.cognitiveFolderHash;
2821
+ if (!cognitiveFolderHash && entry.sourceType === "github" && entry.cognitivePath) {
2822
+ const hash = await fetchCognitiveFolderHash(entry.source, entry.cognitivePath);
2823
+ if (hash) cognitiveFolderHash = hash;
2467
2824
  }
2468
- if (shouldTrack) track({
2469
- event: "install",
2470
- source: telemetry.source,
2471
- skills: items.map((i) => i.installName).join(","),
2472
- agents: targetAgents.join(","),
2473
- ...installGlobally && { global: "1" },
2474
- skillFiles: JSON.stringify(telemetry.skillFiles),
2475
- ...telemetry.sourceType && { sourceType: telemetry.sourceType }
2825
+ await addCognitiveToLock(entry.name, entry.cognitiveType, {
2826
+ source: entry.source,
2827
+ sourceType: entry.sourceType,
2828
+ sourceUrl: entry.sourceUrl,
2829
+ cognitivePath: entry.cognitivePath,
2830
+ cognitiveFolderHash
2476
2831
  });
2477
- }
2478
- if (successful.length > 0 && installGlobally) {
2479
- const successfulSkillNames = new Set(successful.map((r) => r.skill));
2480
- for (const entry of prepared.lockEntries) if (successfulSkillNames.has(entry.name)) try {
2481
- let skillFolderHash = entry.skillFolderHash;
2482
- if (!skillFolderHash && entry.sourceType === "github" && entry.skillPath) {
2483
- const hash = await fetchSkillFolderHash(entry.source, entry.skillPath);
2484
- if (hash) skillFolderHash = hash;
2485
- }
2486
- if (entry.isCognitive) await addCognitiveToLock(entry.name, entry.cognitiveType, {
2487
- source: entry.source,
2488
- sourceType: entry.sourceType,
2489
- sourceUrl: entry.sourceUrl,
2490
- skillPath: entry.skillPath,
2491
- skillFolderHash
2492
- });
2493
- else await addSkillToLock(entry.name, {
2494
- source: entry.source,
2495
- sourceType: entry.sourceType,
2496
- sourceUrl: entry.sourceUrl,
2497
- skillFolderHash
2498
- });
2499
- } catch {}
2500
- }
2832
+ } catch {}
2833
+ }
2834
+ function displayResults(results, targetAgents, cognitiveType, cwd) {
2835
+ const successful = results.filter((r) => r.success);
2836
+ const failed = results.filter((r) => !r.success);
2501
2837
  if (successful.length > 0) {
2502
- const bySkill = /* @__PURE__ */ new Map();
2838
+ const byName = /* @__PURE__ */ new Map();
2503
2839
  for (const r of successful) {
2504
- const skillResults = bySkill.get(r.skill) || [];
2505
- skillResults.push(r);
2506
- bySkill.set(r.skill, skillResults);
2840
+ const group = byName.get(r.name) || [];
2841
+ group.push(r);
2842
+ byName.set(r.name, group);
2507
2843
  }
2508
- const skillCount = bySkill.size;
2844
+ const itemCount = byName.size;
2509
2845
  const resultLines = [];
2510
- for (const [skillName, skillResults] of bySkill) {
2511
- const firstResult = skillResults[0];
2846
+ for (const [itemName, itemResults] of byName) {
2847
+ const firstResult = itemResults[0];
2512
2848
  if (firstResult.mode === "copy") {
2513
- resultLines.push(`${import_picocolors.default.green("✓")} ${skillName} ${import_picocolors.default.dim("(copied)")}`);
2514
- for (const r of skillResults) {
2515
- const shortPath = shortenPath$1(r.path, cwd);
2849
+ resultLines.push(`${import_picocolors.default.green("✓")} ${itemName} ${import_picocolors.default.dim("(copied)")}`);
2850
+ for (const r of itemResults) {
2851
+ const shortPath = shortenPath(r.path, cwd);
2516
2852
  resultLines.push(` ${import_picocolors.default.dim("→")} ${shortPath}`);
2517
2853
  }
2518
2854
  } else {
2519
2855
  if (firstResult.canonicalPath) {
2520
- const shortPath = shortenPath$1(firstResult.canonicalPath, cwd);
2856
+ const shortPath = shortenPath(firstResult.canonicalPath, cwd);
2521
2857
  resultLines.push(`${import_picocolors.default.green("✓")} ${shortPath}`);
2522
- } else resultLines.push(`${import_picocolors.default.green("✓")} ${skillName}`);
2523
- resultLines.push(...buildResultLines(skillResults, targetAgents));
2858
+ } else resultLines.push(`${import_picocolors.default.green("✓")} ${itemName}`);
2859
+ resultLines.push(...buildResultLines(itemResults, targetAgents));
2524
2860
  }
2525
2861
  }
2526
- const title = import_picocolors.default.green(`Installed ${skillCount} skill${skillCount !== 1 ? "s" : ""}`);
2862
+ const title = import_picocolors.default.green(`Installed ${itemCount} ${cognitiveType}${itemCount !== 1 ? "s" : ""}`);
2527
2863
  logger.note(resultLines.join("\n"), title);
2528
2864
  const symlinkFailures = successful.filter((r) => r.mode === "symlink" && r.symlinkFailed);
2529
2865
  if (symlinkFailures.length > 0) {
2530
2866
  const copiedAgentNames = symlinkFailures.map((r) => r.agent);
2531
- logger.warning(import_picocolors.default.yellow(`Symlinks failed for: ${formatList$1(copiedAgentNames)}`));
2867
+ logger.warning(import_picocolors.default.yellow(`Symlinks failed for: ${formatList(copiedAgentNames)}`));
2532
2868
  logger.message(import_picocolors.default.dim("Files were copied instead. On Windows, enable Developer Mode for symlink support."));
2533
2869
  }
2534
2870
  }
2535
2871
  if (failed.length > 0) {
2536
2872
  logger.line();
2537
2873
  logger.error(import_picocolors.default.red(`Failed to install ${failed.length}`));
2538
- for (const r of failed) logger.message(`${import_picocolors.default.red("✗")} ${r.skill} → ${r.agent}: ${import_picocolors.default.dim(r.error)}`);
2874
+ for (const r of failed) logger.message(`${import_picocolors.default.red("✗")} ${r.name} → ${r.agent}: ${import_picocolors.default.dim(r.error)}`);
2875
+ }
2876
+ }
2877
+ async function executeInstallFlow(prepared, options, spinner, cleanup) {
2878
+ const { items, targetAgents, installGlobally, installMode, cognitiveType } = prepared;
2879
+ const cwd = process.cwd();
2880
+ const summaryLines = buildInstallSummary(items, targetAgents, installGlobally, installMode, cognitiveType, await checkOverwrites(items, targetAgents, installGlobally, cognitiveType), cwd);
2881
+ logger.note(summaryLines.join("\n"), "Installation Summary");
2882
+ if (!options.yes) {
2883
+ const confirmed = await ye({ message: "Proceed with installation?" });
2884
+ if (pD(confirmed) || !confirmed) {
2885
+ logger.cancel("Installation cancelled");
2886
+ await cleanup?.();
2887
+ process.exit(0);
2888
+ }
2539
2889
  }
2540
- logger.outro(import_picocolors.default.green("Done!") + import_picocolors.default.dim(" Review skills before use; they run with full agent permissions."));
2890
+ const label = items.length === 1 ? `Installing ${cognitiveType}...` : `Installing ${cognitiveType}s...`;
2891
+ spinner.start(label);
2892
+ const results = await performInstalls(items, targetAgents, installGlobally, installMode);
2893
+ spinner.succeed("Installation complete");
2894
+ logger.line();
2895
+ const successful = results.filter((r) => r.success);
2896
+ const { telemetry } = prepared;
2897
+ if (telemetry.source) {
2898
+ let shouldTrack = true;
2899
+ if (telemetry.checkPrivacy) {
2900
+ if (await isSourcePrivate(telemetry.source) === true) shouldTrack = false;
2901
+ }
2902
+ if (shouldTrack) track({
2903
+ event: "install",
2904
+ source: telemetry.source,
2905
+ skills: items.map((i) => i.installName).join(","),
2906
+ agents: targetAgents.join(","),
2907
+ ...installGlobally && { global: "1" },
2908
+ skillFiles: JSON.stringify(telemetry.skillFiles),
2909
+ ...telemetry.sourceType && { sourceType: telemetry.sourceType }
2910
+ });
2911
+ }
2912
+ if (successful.length > 0 && installGlobally) await writeLockEntries(prepared, new Set(successful.map((r) => r.name)));
2913
+ displayResults(results, targetAgents, cognitiveType, cwd);
2914
+ logger.outro(import_picocolors.default.green("Done!") + import_picocolors.default.dim(" Review cognitives before use; they run with full agent permissions."));
2541
2915
  await promptForFindSkills(options, targetAgents);
2542
2916
  }
2543
- async function selectSkillItems(items, options, cleanup) {
2917
+ async function selectCognitiveItems(items, options, cleanup) {
2918
+ const cognitiveType = options.type ?? "skill";
2919
+ const label = cognitiveType === "skill" ? "skills" : `${cognitiveType}s`;
2544
2920
  if (options.skill?.includes("*")) {
2545
- logger.info(`Installing all ${items.length} skills`);
2921
+ logger.info(`Installing all ${items.length} ${label}`);
2546
2922
  return items;
2547
2923
  }
2548
2924
  if (options.skill && options.skill.length > 0) {
2549
2925
  const selected = items.filter((s) => options.skill.some((name) => "installName" in s && s.installName?.toLowerCase() === name.toLowerCase() || s.name.toLowerCase() === name.toLowerCase()));
2550
2926
  if (selected.length === 0) {
2551
- logger.error(`No matching skills found for: ${options.skill.join(", ")}`);
2552
- logger.info("Available skills:");
2927
+ logger.error(`No matching ${label} found for: ${options.skill.join(", ")}`);
2928
+ logger.info(`Available ${label}:`);
2553
2929
  for (const s of items) logger.message(`- ${"installName" in s ? s.installName : s.name}`);
2554
2930
  await cleanup?.();
2555
2931
  process.exit(1);
2556
2932
  }
2557
- logger.info(`Selected ${selected.length} skill${selected.length !== 1 ? "s" : ""}: ${selected.map((s) => import_picocolors.default.cyan("installName" in s ? s.installName : s.name)).join(", ")}`);
2933
+ logger.info(`Selected ${selected.length} ${cognitiveType}${selected.length !== 1 ? "s" : ""}: ${selected.map((s) => import_picocolors.default.cyan("installName" in s ? s.installName : s.name)).join(", ")}`);
2558
2934
  return selected;
2559
2935
  }
2560
2936
  if (items.length === 1) {
2561
2937
  const first = items[0];
2562
- logger.info(`Skill: ${import_picocolors.default.cyan("installName" in first ? first.installName : first.name)}`);
2938
+ logger.info(`${cognitiveType}: ${import_picocolors.default.cyan("installName" in first ? first.installName : first.name)}`);
2563
2939
  return items;
2564
2940
  }
2565
2941
  if (options.yes) {
2566
- logger.info(`Installing all ${items.length} skills`);
2942
+ logger.info(`Installing all ${items.length} ${label}`);
2567
2943
  return items;
2568
2944
  }
2945
+ const cognitiveChoices = items.map((s) => ({
2946
+ value: s,
2947
+ label: "installName" in s ? s.installName : s.name,
2948
+ hint: s.description.length > 60 ? s.description.slice(0, 57) + "..." : s.description
2949
+ }));
2569
2950
  const selected = await multiselect({
2570
- message: "Select skills to install",
2571
- options: items.map((s) => ({
2572
- value: s,
2573
- label: "installName" in s ? s.installName : s.name,
2574
- hint: s.description.length > 60 ? s.description.slice(0, 57) + "..." : s.description
2575
- })),
2951
+ message: `Select ${label} to install`,
2952
+ options: cognitiveChoices,
2576
2953
  required: true
2577
2954
  });
2578
- if (pD(selected)) {
2579
- logger.cancel("Installation cancelled");
2580
- await cleanup?.();
2581
- process.exit(0);
2582
- }
2955
+ assertNotCancelled(selected, cleanup);
2583
2956
  return selected;
2584
2957
  }
2585
- async function resolveRemoteSkill(source, url, options, spinner) {
2958
+ async function resolveRemoteCognitive(url, options, spinner) {
2586
2959
  const provider = findProvider(url);
2587
- if (!provider) return resolveDirectUrlLegacy(source, url, options, spinner);
2588
- spinner.start(`Fetching skill.md from ${provider.displayName}...`);
2589
- const providerSkill = await provider.fetchSkill(url);
2590
- if (!providerSkill) {
2591
- spinner.fail("Invalid skill");
2592
- logger.outro(import_picocolors.default.red("Could not fetch skill.md or missing required frontmatter (name, description)."));
2960
+ if (!provider) {
2961
+ spinner.fail("Unsupported source host");
2962
+ logger.outro(import_picocolors.default.red("Could not find a provider for this URL. Supported hosts include Mintlify, HuggingFace, and well-known endpoints."));
2593
2963
  process.exit(1);
2594
2964
  }
2595
- const remoteSkill = {
2596
- name: providerSkill.name,
2597
- description: providerSkill.description,
2598
- content: providerSkill.content,
2599
- installName: providerSkill.installName,
2600
- sourceUrl: providerSkill.sourceUrl,
2965
+ const cognitiveType = options.type ?? "skill";
2966
+ const cognitiveFile = COGNITIVE_FILE_NAMES[cognitiveType];
2967
+ spinner.start(`Fetching ${cognitiveFile} from ${provider.displayName}...`);
2968
+ const providerCognitive = await provider.fetchCognitive(url);
2969
+ if (!providerCognitive) {
2970
+ spinner.fail(`Invalid ${cognitiveType}`);
2971
+ logger.outro(import_picocolors.default.red(`Could not fetch ${cognitiveFile} or missing required frontmatter (name, description).`));
2972
+ process.exit(1);
2973
+ }
2974
+ const resolvedType = providerCognitive.cognitiveType ?? cognitiveType;
2975
+ const remoteCognitive = {
2976
+ name: providerCognitive.name,
2977
+ description: providerCognitive.description,
2978
+ content: providerCognitive.content,
2979
+ installName: providerCognitive.installName,
2980
+ sourceUrl: providerCognitive.sourceUrl,
2601
2981
  providerId: provider.id,
2602
2982
  sourceIdentifier: provider.getSourceIdentifier(url),
2603
- metadata: providerSkill.metadata
2983
+ metadata: providerCognitive.metadata,
2984
+ cognitiveType: resolvedType
2604
2985
  };
2605
- spinner.succeed(`Found skill: ${import_picocolors.default.cyan(remoteSkill.installName)}`);
2606
- logger.info(`Skill: ${import_picocolors.default.cyan(remoteSkill.name)}`);
2607
- logger.message(import_picocolors.default.dim(remoteSkill.description));
2608
- logger.message(import_picocolors.default.dim(`Source: ${remoteSkill.sourceIdentifier}`));
2986
+ spinner.succeed(`Found ${resolvedType}: ${import_picocolors.default.cyan(remoteCognitive.installName)}`);
2987
+ logger.info(`${resolvedType}: ${import_picocolors.default.cyan(remoteCognitive.name)}`);
2988
+ logger.message(import_picocolors.default.dim(remoteCognitive.description));
2989
+ logger.message(import_picocolors.default.dim(`Source: ${remoteCognitive.sourceIdentifier}`));
2609
2990
  if (options.list) {
2610
2991
  logger.line();
2611
- logger.step(import_picocolors.default.bold("Skill Details"));
2612
- logger.message(`${import_picocolors.default.cyan("Name:")} ${remoteSkill.name}`);
2613
- logger.message(`${import_picocolors.default.cyan("Install as:")} ${remoteSkill.installName}`);
2992
+ logger.step(import_picocolors.default.bold("Details"));
2993
+ logger.message(`${import_picocolors.default.cyan("Name:")} ${remoteCognitive.name}`);
2994
+ logger.message(`${import_picocolors.default.cyan("Install as:")} ${remoteCognitive.installName}`);
2614
2995
  logger.message(`${import_picocolors.default.cyan("Provider:")} ${provider.displayName}`);
2615
- logger.message(`${import_picocolors.default.cyan("Description:")} ${remoteSkill.description}`);
2996
+ logger.message(`${import_picocolors.default.cyan("Description:")} ${remoteCognitive.description}`);
2616
2997
  logger.outro("Run without --list to install");
2617
2998
  process.exit(0);
2618
2999
  }
2619
- const targetAgents = await selectTargetAgents(options, spinner, void 0, true);
2620
- const installGlobally = await selectInstallScope(options, targetAgents);
2621
- const installMode = await selectInstallMode(options);
3000
+ const { targetAgents, installGlobally, installMode } = await selectInstallContext(options, spinner, void 0, {
3001
+ useUniversalAgents: true,
3002
+ forceMode: provider.id === "mintlify" ? "symlink" : void 0
3003
+ });
2622
3004
  return {
2623
3005
  items: [{
2624
- installName: remoteSkill.installName,
2625
- displayName: remoteSkill.name,
2626
- description: remoteSkill.description,
2627
- sourceIdentifier: remoteSkill.sourceIdentifier,
2628
- providerId: remoteSkill.providerId,
3006
+ installName: remoteCognitive.installName,
3007
+ displayName: remoteCognitive.name,
3008
+ description: remoteCognitive.description,
3009
+ sourceIdentifier: remoteCognitive.sourceIdentifier,
3010
+ providerId: remoteCognitive.providerId,
2629
3011
  sourceUrl: url,
2630
- installFn: (agent, opts) => installRemoteSkillForAgent(remoteSkill, agent, opts)
3012
+ installFn: (agent, opts) => installRemoteCognitiveForAgent(remoteCognitive, agent, {
3013
+ ...opts,
3014
+ cognitiveType: resolvedType
3015
+ })
2631
3016
  }],
2632
3017
  targetAgents,
2633
3018
  installGlobally,
2634
3019
  installMode,
2635
- cognitiveType: "skill",
2636
- lockEntries: [{
2637
- name: remoteSkill.installName,
2638
- source: remoteSkill.sourceIdentifier,
2639
- sourceType: remoteSkill.providerId,
3020
+ cognitiveType: resolvedType,
3021
+ lockEntries: [buildLockEntry({
3022
+ name: remoteCognitive.installName,
3023
+ source: remoteCognitive.sourceIdentifier,
3024
+ sourceType: remoteCognitive.providerId,
2640
3025
  sourceUrl: url,
2641
- skillFolderHash: "",
2642
- cognitiveType: "skill",
2643
- isCognitive: false
2644
- }],
3026
+ cognitiveType: resolvedType
3027
+ })],
2645
3028
  telemetry: {
2646
- source: remoteSkill.sourceIdentifier,
2647
- sourceType: remoteSkill.providerId,
2648
- skillFiles: { [remoteSkill.installName]: url },
3029
+ source: remoteCognitive.sourceIdentifier,
3030
+ sourceType: remoteCognitive.providerId,
3031
+ skillFiles: { [remoteCognitive.installName]: url },
2649
3032
  checkPrivacy: true
2650
3033
  }
2651
3034
  };
2652
3035
  }
2653
- async function resolveDirectUrlLegacy(source, url, options, spinner) {
2654
- spinner.start("Fetching skill.md...");
2655
- const mintlifySkill = await fetchMintlifySkill(url);
2656
- if (!mintlifySkill) {
2657
- spinner.fail("Invalid skill");
2658
- logger.outro(import_picocolors.default.red("Could not fetch skill.md or missing required frontmatter (name, description, mintlify-proj)."));
2659
- process.exit(1);
2660
- }
2661
- const remoteSkill = {
2662
- name: mintlifySkill.name,
2663
- description: mintlifySkill.description,
2664
- content: mintlifySkill.content,
2665
- installName: mintlifySkill.mintlifySite,
2666
- sourceUrl: mintlifySkill.sourceUrl,
2667
- providerId: "mintlify",
2668
- sourceIdentifier: "mintlify/com"
2669
- };
2670
- spinner.succeed(`Found skill: ${import_picocolors.default.cyan(remoteSkill.installName)}`);
2671
- logger.info(`Skill: ${import_picocolors.default.cyan(remoteSkill.name)}`);
2672
- logger.message(import_picocolors.default.dim(remoteSkill.description));
2673
- if (options.list) {
2674
- logger.line();
2675
- logger.step(import_picocolors.default.bold("Skill Details"));
2676
- logger.message(`${import_picocolors.default.cyan("Name:")} ${remoteSkill.name}`);
2677
- logger.message(`${import_picocolors.default.cyan("Site:")} ${remoteSkill.installName}`);
2678
- logger.message(`${import_picocolors.default.cyan("Description:")} ${remoteSkill.description}`);
2679
- logger.outro("Run without --list to install");
2680
- process.exit(0);
2681
- }
2682
- const targetAgents = await selectTargetAgents(options, spinner);
2683
- const installGlobally = await selectInstallScope(options, targetAgents);
2684
- return {
2685
- items: [{
2686
- installName: remoteSkill.installName,
2687
- displayName: remoteSkill.name,
2688
- description: remoteSkill.description,
2689
- sourceIdentifier: "mintlify/com",
2690
- providerId: "mintlify",
2691
- sourceUrl: url,
2692
- installFn: (agent, opts) => installRemoteSkillForAgent(remoteSkill, agent, opts)
2693
- }],
2694
- targetAgents,
2695
- installGlobally,
2696
- installMode: "symlink",
2697
- cognitiveType: "skill",
2698
- lockEntries: [{
2699
- name: remoteSkill.installName,
2700
- source: `mintlify/${remoteSkill.installName}`,
2701
- sourceType: "mintlify",
2702
- sourceUrl: url,
2703
- skillFolderHash: "",
2704
- cognitiveType: "skill",
2705
- isCognitive: false
2706
- }],
2707
- telemetry: {
2708
- source: "mintlify/com",
2709
- sourceType: "mintlify",
2710
- skillFiles: { [remoteSkill.installName]: url },
2711
- checkPrivacy: false
2712
- }
2713
- };
2714
- }
2715
- async function resolveWellKnownSkills(source, url, options, spinner) {
2716
- spinner.start("Discovering skills from well-known endpoint...");
2717
- const skills = await wellKnownProvider.fetchAllSkills(url);
2718
- if (skills.length === 0) {
2719
- spinner.fail("No skills found");
2720
- logger.outro(import_picocolors.default.red("No skills found at this URL. Make sure the server has a /.well-known/skills/index.json file."));
3036
+ async function resolveWellKnownCognitives(url, options, spinner) {
3037
+ const cognitiveType = options.type ?? "skill";
3038
+ const label = cognitiveType === "skill" ? "skills" : `${cognitiveType}s`;
3039
+ spinner.start(`Discovering ${label} from well-known endpoint...`);
3040
+ const cognitives = await wellKnownProvider.fetchAllCognitives(url);
3041
+ if (cognitives.length === 0) {
3042
+ spinner.fail(`No ${label} found`);
3043
+ logger.outro(import_picocolors.default.red(`No ${label} found at this URL. Make sure the server has a /.well-known/skills/index.json file.`));
2721
3044
  process.exit(1);
2722
3045
  }
2723
- spinner.succeed(`Found ${import_picocolors.default.green(skills.length)} skill${skills.length > 1 ? "s" : ""}`);
2724
- for (const skill of skills) {
2725
- logger.info(`Skill: ${import_picocolors.default.cyan(skill.installName)}`);
2726
- logger.message(import_picocolors.default.dim(skill.description));
2727
- if (skill.files.size > 1) logger.message(import_picocolors.default.dim(` Files: ${Array.from(skill.files.keys()).join(", ")}`));
3046
+ spinner.succeed(`Found ${import_picocolors.default.green(cognitives.length)} ${cognitiveType}${cognitives.length > 1 ? "s" : ""}`);
3047
+ for (const item of cognitives) {
3048
+ logger.info(`${cognitiveType}: ${import_picocolors.default.cyan(item.installName)}`);
3049
+ logger.message(import_picocolors.default.dim(item.description));
3050
+ if (item.files.size > 1) logger.message(import_picocolors.default.dim(` Files: ${Array.from(item.files.keys()).join(", ")}`));
2728
3051
  }
2729
3052
  if (options.list) {
2730
3053
  logger.line();
2731
- logger.step(import_picocolors.default.bold("Available Skills"));
2732
- for (const skill of skills) {
2733
- logger.message(`${import_picocolors.default.cyan(skill.installName)}`);
2734
- logger.message(` ${import_picocolors.default.dim(skill.description)}`);
2735
- if (skill.files.size > 1) logger.message(` ${import_picocolors.default.dim(`Files: ${skill.files.size}`)}`);
3054
+ logger.step(import_picocolors.default.bold(`Available ${label}`));
3055
+ for (const item of cognitives) {
3056
+ logger.message(`${import_picocolors.default.cyan(item.installName)}`);
3057
+ logger.message(` ${import_picocolors.default.dim(item.description)}`);
3058
+ if (item.files.size > 1) logger.message(` ${import_picocolors.default.dim(`Files: ${item.files.size}`)}`);
2736
3059
  }
2737
3060
  logger.outro("Run without --list to install");
2738
3061
  process.exit(0);
2739
3062
  }
2740
- const selectedSkills = await selectSkillItems(skills, options);
2741
- const targetAgents = await selectTargetAgents(options, spinner);
2742
- const installGlobally = await selectInstallScope(options, targetAgents);
2743
- const installMode = await selectInstallMode(options);
3063
+ const selectedCognitives = await selectCognitiveItems(cognitives, options);
3064
+ const { targetAgents, installGlobally, installMode } = await selectInstallContext(options, spinner);
2744
3065
  const sourceIdentifier = wellKnownProvider.getSourceIdentifier(url);
2745
- const items = selectedSkills.map((skill) => ({
2746
- installName: skill.installName,
2747
- displayName: skill.name,
2748
- description: skill.description,
3066
+ const items = selectedCognitives.map((cog) => ({
3067
+ installName: cog.installName,
3068
+ displayName: cog.name,
3069
+ description: cog.description,
2749
3070
  sourceIdentifier,
2750
3071
  providerId: "well-known",
2751
- sourceUrl: skill.sourceUrl,
2752
- fileCount: skill.files.size,
2753
- installFn: (agent, opts) => installWellKnownSkillForAgent(skill, agent, opts)
3072
+ sourceUrl: cog.sourceUrl,
3073
+ fileCount: cog.files.size,
3074
+ installFn: (agent, opts) => installWellKnownCognitiveForAgent(cog, agent, opts)
2754
3075
  }));
2755
- const skillFiles = {};
3076
+ const telemetryFiles = {};
2756
3077
  const lockEntries = [];
2757
- for (const skill of selectedSkills) {
2758
- skillFiles[skill.installName] = skill.sourceUrl;
2759
- lockEntries.push({
2760
- name: skill.installName,
3078
+ for (const cog of selectedCognitives) {
3079
+ telemetryFiles[cog.installName] = cog.sourceUrl;
3080
+ lockEntries.push(buildLockEntry({
3081
+ name: cog.installName,
2761
3082
  source: sourceIdentifier,
2762
3083
  sourceType: "well-known",
2763
- sourceUrl: skill.sourceUrl,
2764
- skillFolderHash: "",
2765
- cognitiveType: "skill",
2766
- isCognitive: false
2767
- });
3084
+ sourceUrl: cog.sourceUrl,
3085
+ cognitiveType: cog.cognitiveType ?? cognitiveType
3086
+ }));
2768
3087
  }
2769
3088
  return {
2770
3089
  items,
2771
3090
  targetAgents,
2772
3091
  installGlobally,
2773
3092
  installMode,
2774
- cognitiveType: "skill",
3093
+ cognitiveType: selectedCognitives[0]?.cognitiveType ?? cognitiveType,
2775
3094
  lockEntries,
2776
3095
  telemetry: {
2777
3096
  source: sourceIdentifier,
2778
3097
  sourceType: "well-known",
2779
- skillFiles,
3098
+ skillFiles: telemetryFiles,
2780
3099
  checkPrivacy: true
2781
3100
  }
2782
3101
  };
2783
3102
  }
2784
- async function resolveGitRepoSkills(source, parsed, options, spinner, skillsDir, tempDir) {
3103
+ async function resolveGitRepoCognitives(source, parsed, options, spinner, sourceDir, tempDir) {
2785
3104
  const cleanupFn = async () => {
2786
3105
  await cleanupDir(tempDir);
2787
3106
  };
2788
3107
  const cognitiveType = options.type ?? "skill";
2789
- const cognitiveLabel = cognitiveType === "skill" ? "skills" : `${cognitiveType}s`;
2790
- const cognitiveFile = cognitiveType === "skill" ? "SKILL.md" : cognitiveType === "agent" ? "AGENT.md" : "PROMPT.md";
3108
+ const label = cognitiveType === "skill" ? "skills" : `${cognitiveType}s`;
3109
+ const cognitiveFile = COGNITIVE_FILE_NAMES[cognitiveType];
2791
3110
  const includeInternal = !!(options.skill && options.skill.length > 0);
2792
- spinner.start(`Discovering ${cognitiveLabel}...`);
2793
- const skills = options.type ? await discoverCognitives(skillsDir, parsed.subpath, {
3111
+ spinner.start(`Discovering ${label}...`);
3112
+ const cognitives = await discoverCognitives(sourceDir, parsed.subpath, {
2794
3113
  includeInternal,
2795
3114
  fullDepth: options.fullDepth,
2796
- types: [options.type]
2797
- }) : await discoverSkills(skillsDir, parsed.subpath, {
2798
- includeInternal,
2799
- fullDepth: options.fullDepth
3115
+ types: options.type ? [options.type] : ["skill"]
2800
3116
  });
2801
- if (skills.length === 0) {
2802
- spinner.fail(`No ${cognitiveLabel} found`);
2803
- logger.outro(import_picocolors.default.red(`No valid ${cognitiveLabel} found. They require a ${cognitiveFile} with name and description.`));
3117
+ if (cognitives.length === 0) {
3118
+ spinner.fail(`No ${label} found`);
3119
+ logger.outro(import_picocolors.default.red(`No valid ${label} found. They require a ${cognitiveFile} with name and description.`));
2804
3120
  await cleanupFn();
2805
3121
  process.exit(1);
2806
3122
  }
2807
- spinner.succeed(`Found ${import_picocolors.default.green(skills.length)} skill${skills.length > 1 ? "s" : ""}`);
3123
+ spinner.succeed(`Found ${import_picocolors.default.green(cognitives.length)} ${cognitiveType}${cognitives.length > 1 ? "s" : ""}`);
2808
3124
  if (options.list) {
2809
3125
  logger.line();
2810
- logger.step(import_picocolors.default.bold("Available Skills"));
2811
- for (const skill of skills) {
2812
- logger.message(`${import_picocolors.default.cyan(getSkillDisplayName(skill))}`);
2813
- logger.message(` ${import_picocolors.default.dim(skill.description)}`);
3126
+ logger.step(import_picocolors.default.bold(`Available ${label}`));
3127
+ for (const cog of cognitives) {
3128
+ logger.message(`${import_picocolors.default.cyan(getCognitiveDisplayName(cog))}`);
3129
+ logger.message(` ${import_picocolors.default.dim(cog.description)}`);
2814
3130
  }
2815
- logger.outro("Use --skill <name> to install specific skills");
3131
+ logger.outro(`Use --skill <name> to install specific ${label}`);
2816
3132
  await cleanupFn();
2817
3133
  process.exit(0);
2818
3134
  }
2819
- let selectedSkills;
2820
- if (options.skill?.includes("*")) {
2821
- selectedSkills = skills;
2822
- logger.info(`Installing all ${skills.length} skills`);
2823
- } else if (options.skill && options.skill.length > 0) {
2824
- selectedSkills = filterSkills(skills, options.skill);
2825
- if (selectedSkills.length === 0) {
2826
- logger.error(`No matching skills found for: ${options.skill.join(", ")}`);
2827
- logger.info("Available skills:");
2828
- for (const s of skills) logger.message(`- ${getSkillDisplayName(s)}`);
3135
+ let selectedCognitives;
3136
+ if (options.skill && options.skill.length > 0 && !options.skill.includes("*")) {
3137
+ selectedCognitives = filterCognitives(cognitives, options.skill);
3138
+ if (selectedCognitives.length === 0) {
3139
+ logger.error(`No matching ${label} found for: ${options.skill.join(", ")}`);
3140
+ logger.info(`Available ${label}:`);
3141
+ for (const s of cognitives) logger.message(`- ${getCognitiveDisplayName(s)}`);
2829
3142
  await cleanupFn();
2830
3143
  process.exit(1);
2831
3144
  }
2832
- logger.info(`Selected ${selectedSkills.length} skill${selectedSkills.length !== 1 ? "s" : ""}: ${selectedSkills.map((s) => import_picocolors.default.cyan(getSkillDisplayName(s))).join(", ")}`);
2833
- } else if (skills.length === 1) {
2834
- selectedSkills = skills;
2835
- const firstSkill = skills[0];
2836
- logger.info(`Skill: ${import_picocolors.default.cyan(getSkillDisplayName(firstSkill))}`);
2837
- logger.message(import_picocolors.default.dim(firstSkill.description));
2838
- } else if (options.yes) {
2839
- selectedSkills = skills;
2840
- logger.info(`Installing all ${skills.length} skills`);
2841
- } else {
2842
- const selected = await multiselect({
2843
- message: "Select skills to install",
2844
- options: skills.map((s) => ({
2845
- value: s,
2846
- label: getSkillDisplayName(s),
2847
- hint: s.description.length > 60 ? s.description.slice(0, 57) + "..." : s.description
2848
- })),
2849
- required: true
2850
- });
2851
- if (pD(selected)) {
2852
- logger.cancel("Installation cancelled");
2853
- await cleanupFn();
2854
- process.exit(0);
2855
- }
2856
- selectedSkills = selected;
2857
- }
2858
- const targetAgents = await selectTargetAgents(options, spinner, cleanupFn);
2859
- const installGlobally = await selectInstallScope(options, targetAgents, cleanupFn);
2860
- const installMode = await selectInstallMode(options, cleanupFn);
3145
+ logger.info(`Selected ${selectedCognitives.length} ${cognitiveType}${selectedCognitives.length !== 1 ? "s" : ""}: ${selectedCognitives.map((s) => import_picocolors.default.cyan(getCognitiveDisplayName(s))).join(", ")}`);
3146
+ } else selectedCognitives = (await selectCognitiveItems(cognitives.map((s) => ({
3147
+ installName: s.name,
3148
+ name: getCognitiveDisplayName(s),
3149
+ description: s.description
3150
+ })), options, cleanupFn)).map((s) => cognitives.find((c) => c.name === s.installName));
3151
+ const { targetAgents, installGlobally, installMode } = await selectInstallContext(options, spinner, cleanupFn);
2861
3152
  const normalizedSource = getOwnerRepo(parsed);
2862
- const skillFiles = {};
2863
- for (const skill of selectedSkills) {
3153
+ const telemetryFiles = {};
3154
+ for (const cog of selectedCognitives) {
2864
3155
  let relativePath;
2865
- if (tempDir && skill.path === tempDir) relativePath = cognitiveFile;
2866
- else if (tempDir && skill.path.startsWith(tempDir + sep)) relativePath = skill.path.slice(tempDir.length + 1).split(sep).join("/") + `/${cognitiveFile}`;
3156
+ if (tempDir && cog.path === tempDir) relativePath = cognitiveFile;
3157
+ else if (tempDir && cog.path.startsWith(tempDir + sep)) relativePath = cog.path.slice(tempDir.length + 1).split(sep).join("/") + `/${cognitiveFile}`;
2867
3158
  else continue;
2868
- skillFiles[skill.name] = relativePath;
3159
+ telemetryFiles[cog.name] = relativePath;
2869
3160
  }
2870
- const items = selectedSkills.map((skill) => ({
2871
- installName: skill.name,
2872
- displayName: getSkillDisplayName(skill),
2873
- description: skill.description,
3161
+ const items = selectedCognitives.map((cog) => ({
3162
+ installName: cog.name,
3163
+ displayName: getCognitiveDisplayName(cog),
3164
+ description: cog.description,
2874
3165
  sourceIdentifier: normalizedSource ?? source,
2875
3166
  providerId: parsed.type,
2876
3167
  sourceUrl: parsed.url,
2877
- installFn: (agent, opts) => installCognitiveForAgent(skill, agent, {
3168
+ installFn: (agent, opts) => installCognitiveForAgent(cog, agent, {
2878
3169
  ...opts,
2879
3170
  cognitiveType
2880
3171
  })
2881
3172
  }));
2882
3173
  const lockEntries = [];
2883
- if (normalizedSource) for (const skill of selectedSkills) lockEntries.push({
2884
- name: getSkillDisplayName(skill),
3174
+ if (normalizedSource) for (const cog of selectedCognitives) lockEntries.push(buildLockEntry({
3175
+ name: getCognitiveDisplayName(cog),
2885
3176
  source: normalizedSource,
2886
3177
  sourceType: parsed.type,
2887
3178
  sourceUrl: parsed.url,
2888
- skillPath: skillFiles[skill.name],
2889
- skillFolderHash: "",
2890
- cognitiveType,
2891
- isCognitive: true
2892
- });
3179
+ cognitivePath: telemetryFiles[cog.name],
3180
+ cognitiveType
3181
+ }));
2893
3182
  let telemetrySource = normalizedSource ?? "";
2894
3183
  if (normalizedSource) {
2895
3184
  const ownerRepo = parseOwnerRepo(normalizedSource);
2896
- if (ownerRepo) if (await isRepoPrivate(ownerRepo.owner, ownerRepo.repo) === false) {} else telemetrySource = "";
3185
+ if (ownerRepo) {
3186
+ if (await isRepoPrivate(ownerRepo.owner, ownerRepo.repo) !== false) telemetrySource = "";
3187
+ }
2897
3188
  }
2898
3189
  return {
2899
3190
  items,
@@ -2904,7 +3195,7 @@ async function resolveGitRepoSkills(source, parsed, options, spinner, skillsDir,
2904
3195
  lockEntries,
2905
3196
  telemetry: {
2906
3197
  source: telemetrySource,
2907
- skillFiles,
3198
+ skillFiles: telemetryFiles,
2908
3199
  checkPrivacy: false
2909
3200
  }
2910
3201
  };
@@ -2941,16 +3232,16 @@ async function runAdd(args, options = {}) {
2941
3232
  const spinner = logger.spinner();
2942
3233
  spinner.start("Parsing source...");
2943
3234
  const parsed = parseSource(source);
2944
- spinner.succeed(`Source: ${parsed.type === "local" ? parsed.localPath : parsed.url}${parsed.ref ? ` @ ${import_picocolors.default.yellow(parsed.ref)}` : ""}${parsed.subpath ? ` (${parsed.subpath})` : ""}${parsed.skillFilter ? ` ${import_picocolors.default.dim("@")}${import_picocolors.default.cyan(parsed.skillFilter)}` : ""}`);
3235
+ spinner.succeed(`Source: ${parsed.type === "local" ? parsed.localPath : parsed.url}${parsed.ref ? ` @ ${import_picocolors.default.yellow(parsed.ref)}` : ""}${parsed.subpath ? ` (${parsed.subpath})` : ""}${parsed.nameFilter ? ` ${import_picocolors.default.dim("@")}${import_picocolors.default.cyan(parsed.nameFilter)}` : ""}`);
2945
3236
  if (parsed.type === "direct-url") {
2946
- await executeInstallFlow(await resolveRemoteSkill(source, parsed.url, options, spinner), options, spinner);
3237
+ await executeInstallFlow(await resolveRemoteCognitive(parsed.url, options, spinner), options, spinner);
2947
3238
  return;
2948
3239
  }
2949
3240
  if (parsed.type === "well-known") {
2950
- await executeInstallFlow(await resolveWellKnownSkills(source, parsed.url, options, spinner), options, spinner);
3241
+ await executeInstallFlow(await resolveWellKnownCognitives(parsed.url, options, spinner), options, spinner);
2951
3242
  return;
2952
3243
  }
2953
- let skillsDir;
3244
+ let sourceDir;
2954
3245
  if (parsed.type === "local") {
2955
3246
  spinner.start("Validating local path...");
2956
3247
  if (!existsSync(parsed.localPath)) {
@@ -2958,19 +3249,19 @@ async function runAdd(args, options = {}) {
2958
3249
  logger.outro(import_picocolors.default.red(`Local path does not exist: ${parsed.localPath}`));
2959
3250
  process.exit(1);
2960
3251
  }
2961
- skillsDir = parsed.localPath;
3252
+ sourceDir = parsed.localPath;
2962
3253
  spinner.succeed("Local path validated");
2963
3254
  } else {
2964
3255
  spinner.start("Cloning repository...");
2965
3256
  tempDir = await cloneRepo(parsed.url, parsed.ref);
2966
- skillsDir = tempDir;
3257
+ sourceDir = tempDir;
2967
3258
  spinner.succeed("Repository cloned");
2968
3259
  }
2969
- if (parsed.skillFilter) {
3260
+ if (parsed.nameFilter) {
2970
3261
  options.skill = options.skill || [];
2971
- if (!options.skill.includes(parsed.skillFilter)) options.skill.push(parsed.skillFilter);
3262
+ if (!options.skill.includes(parsed.nameFilter)) options.skill.push(parsed.nameFilter);
2972
3263
  }
2973
- const prepared = await resolveGitRepoSkills(source, parsed, options, spinner, skillsDir, tempDir);
3264
+ const prepared = await resolveGitRepoCognitives(source, parsed, options, spinner, sourceDir, tempDir);
2974
3265
  const cleanupFn = async () => {
2975
3266
  await cleanupDir(tempDir);
2976
3267
  };
@@ -2997,7 +3288,7 @@ async function promptForFindSkills(options, targetAgents) {
2997
3288
  if (options?.yes) return;
2998
3289
  try {
2999
3290
  if (await isPromptDismissed("findSkillsPrompt")) return;
3000
- if (await isSkillInstalled("find-skills", "claude-code", { global: true })) {
3291
+ if (await isCognitiveInstalled("find-skills", "claude-code", "skill", { global: true })) {
3001
3292
  await dismissPrompt("findSkillsPrompt");
3002
3293
  return;
3003
3294
  }
@@ -3063,7 +3354,7 @@ function parseAddOptions(args) {
3063
3354
  } else if (arg === "-t" || arg === "--type") {
3064
3355
  i++;
3065
3356
  const typeVal = args[i];
3066
- if (typeVal === "skill" || typeVal === "agent" || typeVal === "prompt") options.type = typeVal;
3357
+ if (typeVal && Object.keys(COGNITIVE_FILE_NAMES).includes(typeVal)) options.type = typeVal;
3067
3358
  } else if (arg === "--full-depth") options.fullDepth = true;
3068
3359
  else if (arg && !arg.startsWith("-")) source.push(arg);
3069
3360
  }
@@ -3280,18 +3571,6 @@ ${import_picocolors.default.dim(" 2) npx synk add <owner/repo@skill>")}`;
3280
3571
  else logger.log(`${import_picocolors.default.dim("Discover more skills at")} https://skills.sh`);
3281
3572
  logger.line();
3282
3573
  }
3283
- function shortenPath(fullPath, cwd) {
3284
- const home = homedir();
3285
- if (fullPath.startsWith(home)) return fullPath.replace(home, "~");
3286
- if (fullPath.startsWith(cwd)) return "." + fullPath.slice(cwd.length);
3287
- return fullPath;
3288
- }
3289
- function formatList(items, maxShow = 5) {
3290
- if (items.length <= maxShow) return items.join(", ");
3291
- const shown = items.slice(0, maxShow);
3292
- const remaining = items.length - maxShow;
3293
- return `${shown.join(", ")} +${remaining} more`;
3294
- }
3295
3574
  function parseListOptions(args) {
3296
3575
  const options = {};
3297
3576
  for (let i = 0; i < args.length; i++) {
@@ -3303,7 +3582,7 @@ function parseListOptions(args) {
3303
3582
  } else if (arg === "-t" || arg === "--type") {
3304
3583
  i++;
3305
3584
  const typeVal = args[i];
3306
- if (typeVal === "skill" || typeVal === "agent" || typeVal === "prompt") options.type = typeVal;
3585
+ if (typeVal && Object.keys(COGNITIVE_FILE_NAMES).includes(typeVal)) options.type = typeVal;
3307
3586
  }
3308
3587
  }
3309
3588
  return options;
@@ -3312,25 +3591,16 @@ async function runList(args) {
3312
3591
  const options = parseListOptions(args);
3313
3592
  const scope = options.global === true ? true : false;
3314
3593
  let agentFilter;
3315
- if (options.agent && options.agent.length > 0) {
3316
- const validAgents = Object.keys(agents);
3317
- const invalidAgents = options.agent.filter((a) => !validAgents.includes(a));
3318
- if (invalidAgents.length > 0) {
3319
- logger.warning(`Invalid agents: ${invalidAgents.join(", ")}`);
3320
- logger.dim(`Valid agents: ${validAgents.join(", ")}`);
3321
- process.exit(1);
3322
- }
3323
- agentFilter = options.agent;
3324
- }
3325
- const installedSkills = await listInstalledSkills({
3594
+ if (options.agent && options.agent.length > 0) agentFilter = validateAgentNames(options.agent);
3595
+ const installedCognitives = await listInstalledCognitives({
3326
3596
  global: scope,
3327
3597
  agentFilter
3328
3598
  });
3329
- const filteredSkills = options.type ? installedSkills.filter((s) => (s.cognitiveType || "skill") === options.type) : installedSkills;
3599
+ const filteredCognitives = options.type ? installedCognitives.filter((s) => (s.cognitiveType || "skill") === options.type) : installedCognitives;
3330
3600
  const cwd = process.cwd();
3331
3601
  const scopeLabel = scope ? "Global" : "Project";
3332
3602
  const typeLabel = options.type ? ` ${options.type}s` : "";
3333
- if (filteredSkills.length === 0) {
3603
+ if (filteredCognitives.length === 0) {
3334
3604
  logger.dim(`No ${scopeLabel.toLowerCase()}${typeLabel} found.`);
3335
3605
  if (scope) logger.dim("Try listing project cognitives without -g");
3336
3606
  else logger.dim("Try listing global cognitives with -g");
@@ -3351,13 +3621,13 @@ async function runList(args) {
3351
3621
  }
3352
3622
  logger.bold(`${scopeLabel}${typeLabel ? typeLabel.charAt(0).toUpperCase() + typeLabel.slice(1) : " Cognitives"}`);
3353
3623
  logger.line();
3354
- for (const skill of filteredSkills) printSkill(skill);
3624
+ for (const skill of filteredCognitives) printSkill(skill);
3355
3625
  logger.line();
3356
3626
  }
3357
3627
  async function removeCommand(skillNames, options) {
3358
3628
  const isGlobal = options.global ?? false;
3359
3629
  const cwd = process.cwd();
3360
- const spinner = logger.spinner("Scanning for installed skills...");
3630
+ const spinner = logger.spinner("Scanning for installed cognitives...");
3361
3631
  const skillNamesSet = /* @__PURE__ */ new Set();
3362
3632
  const scanDir = async (dir) => {
3363
3633
  try {
@@ -3367,36 +3637,27 @@ async function removeCommand(skillNames, options) {
3367
3637
  if (err instanceof Error && err.code !== "ENOENT") logger.warning(`Could not scan directory ${dir}: ${err.message}`);
3368
3638
  }
3369
3639
  };
3370
- const typesToScan = options.type ? [options.type] : [
3371
- "skill",
3372
- "agent",
3373
- "prompt"
3374
- ];
3640
+ const typesToScan = options.type ? [options.type] : Object.keys(COGNITIVE_FILE_NAMES);
3375
3641
  for (const cogType of typesToScan) if (isGlobal) {
3376
3642
  await scanDir(getCanonicalDir(cogType, true, cwd));
3377
3643
  for (const agent of Object.values(agents)) {
3378
- const dir = cogType === "skill" ? agent.globalSkillsDir : cogType === "agent" ? agent.globalAgentsDir : agent.globalPromptsDir;
3644
+ const dir = agent.dirs[cogType].global;
3379
3645
  if (dir !== void 0) await scanDir(dir);
3380
3646
  }
3381
3647
  } else {
3382
3648
  await scanDir(getCanonicalDir(cogType, false, cwd));
3383
- for (const agent of Object.values(agents)) await scanDir(join(cwd, cogType === "skill" ? agent.skillsDir : cogType === "agent" ? agent.agentsDir : agent.promptsDir));
3649
+ for (const agent of Object.values(agents)) {
3650
+ const dir = agent.dirs[cogType].local;
3651
+ await scanDir(join(cwd, dir));
3652
+ }
3384
3653
  }
3385
3654
  const installedSkills = Array.from(skillNamesSet).sort();
3386
- spinner.succeed(`Found ${installedSkills.length} unique installed skill(s)`);
3655
+ spinner.succeed(`Found ${installedSkills.length} unique installed cognitive(s)`);
3387
3656
  if (installedSkills.length === 0) {
3388
- logger.outro(import_picocolors.default.yellow("No skills found to remove."));
3657
+ logger.outro(import_picocolors.default.yellow("No cognitives found to remove."));
3389
3658
  return;
3390
3659
  }
3391
- if (options.agent && options.agent.length > 0) {
3392
- const validAgents = Object.keys(agents);
3393
- const invalidAgents = options.agent.filter((a) => !validAgents.includes(a));
3394
- if (invalidAgents.length > 0) {
3395
- logger.error(`Invalid agents: ${invalidAgents.join(", ")}`);
3396
- logger.info(`Valid agents: ${validAgents.join(", ")}`);
3397
- process.exit(1);
3398
- }
3399
- }
3660
+ if (options.agent && options.agent.length > 0) validateAgentNames(options.agent);
3400
3661
  let selectedSkills = [];
3401
3662
  if (options.all) selectedSkills = installedSkills;
3402
3663
  else if (skillNames.length > 0) {
@@ -3411,14 +3672,11 @@ async function removeCommand(skillNames, options) {
3411
3672
  label: s
3412
3673
  }));
3413
3674
  const selected = await fe({
3414
- message: `Select skills to remove ${import_picocolors.default.dim("(space to toggle)")}`,
3675
+ message: `Select cognitives to remove ${import_picocolors.default.dim("(space to toggle)")}`,
3415
3676
  options: choices,
3416
3677
  required: true
3417
3678
  });
3418
- if (pD(selected)) {
3419
- logger.cancel("Removal cancelled");
3420
- process.exit(0);
3421
- }
3679
+ assertNotCancelled(selected);
3422
3680
  selectedSkills = selected;
3423
3681
  }
3424
3682
  let targetAgents;
@@ -3431,16 +3689,17 @@ async function removeCommand(skillNames, options) {
3431
3689
  }
3432
3690
  if (!options.yes) {
3433
3691
  logger.line();
3434
- logger.info("Skills to remove:");
3692
+ logger.info("Cognitives to remove:");
3435
3693
  for (const skill of selectedSkills) logger.message(`${import_picocolors.default.red("•")} ${skill}`);
3436
3694
  logger.line();
3437
- const confirmed = await ye({ message: `Are you sure you want to uninstall ${selectedSkills.length} skill(s)?` });
3438
- if (pD(confirmed) || !confirmed) {
3695
+ const confirmed = await ye({ message: `Are you sure you want to uninstall ${selectedSkills.length} cognitive(s)?` });
3696
+ assertNotCancelled(confirmed);
3697
+ if (!confirmed) {
3439
3698
  logger.cancel("Removal cancelled");
3440
3699
  process.exit(0);
3441
3700
  }
3442
3701
  }
3443
- spinner.start("Removing skills...");
3702
+ spinner.start("Removing cognitives...");
3444
3703
  const results = [];
3445
3704
  for (const skillName of selectedSkills) try {
3446
3705
  for (const agentKey of targetAgents) {
@@ -3466,10 +3725,10 @@ async function removeCommand(skillNames, options) {
3466
3725
  recursive: true,
3467
3726
  force: true
3468
3727
  });
3469
- const lockEntry = isGlobal ? await getSkillFromLock(skillName) : null;
3728
+ const lockEntry = isGlobal ? await getCognitiveFromLock(skillName) : null;
3470
3729
  const effectiveSource = lockEntry?.source || "local";
3471
3730
  const effectiveSourceType = lockEntry?.sourceType || "local";
3472
- if (isGlobal) await removeSkillFromLock(skillName);
3731
+ if (isGlobal) await removeCognitiveFromLock(skillName);
3473
3732
  results.push({
3474
3733
  skill: skillName,
3475
3734
  success: true,
@@ -3504,9 +3763,9 @@ async function removeCommand(skillNames, options) {
3504
3763
  sourceType: data.sourceType
3505
3764
  });
3506
3765
  }
3507
- if (successful.length > 0) logger.success(import_picocolors.default.green(`Successfully removed ${successful.length} skill(s)`));
3766
+ if (successful.length > 0) logger.success(import_picocolors.default.green(`Successfully removed ${successful.length} cognitive(s)`));
3508
3767
  if (failed.length > 0) {
3509
- logger.error(import_picocolors.default.red(`Failed to remove ${failed.length} skill(s)`));
3768
+ logger.error(import_picocolors.default.red(`Failed to remove ${failed.length} cognitive(s)`));
3510
3769
  for (const r of failed) logger.message(`${import_picocolors.default.red("✗")} ${r.skill}: ${r.error}`);
3511
3770
  }
3512
3771
  logger.line();
@@ -3533,7 +3792,7 @@ function parseRemoveOptions(args) {
3533
3792
  } else if (arg === "-t" || arg === "--type") {
3534
3793
  i++;
3535
3794
  const typeVal = args[i];
3536
- if (typeVal === "skill" || typeVal === "agent" || typeVal === "prompt") options.type = typeVal;
3795
+ if (typeVal && Object.keys(COGNITIVE_FILE_NAMES).includes(typeVal)) options.type = typeVal;
3537
3796
  } else if (arg && !arg.startsWith("-")) skills.push(arg);
3538
3797
  }
3539
3798
  return {
@@ -3549,17 +3808,13 @@ function runInit(args) {
3549
3808
  const arg = args[i];
3550
3809
  if ((arg === "-t" || arg === "--type") && i + 1 < args.length) {
3551
3810
  const typeVal = args[i + 1];
3552
- if (typeVal === "skill" || typeVal === "agent" || typeVal === "prompt") cognitiveType = typeVal;
3811
+ if (typeVal && Object.keys(COGNITIVE_FILE_NAMES).includes(typeVal)) cognitiveType = typeVal;
3553
3812
  i++;
3554
3813
  } else if (arg && !arg.startsWith("-")) filteredArgs.push(arg);
3555
3814
  }
3556
3815
  const itemName = filteredArgs[0] || basename(cwd);
3557
3816
  const hasName = filteredArgs[0] !== void 0;
3558
- const fileName = {
3559
- skill: "SKILL.md",
3560
- agent: "AGENT.md",
3561
- prompt: "PROMPT.md"
3562
- }[cognitiveType];
3817
+ const fileName = COGNITIVE_FILE_NAMES[cognitiveType];
3563
3818
  const itemDir = hasName ? join(cwd, itemName) : cwd;
3564
3819
  const itemFile = join(itemDir, fileName);
3565
3820
  const displayPath = hasName ? `${itemName}/${fileName}` : fileName;
@@ -3639,70 +3894,43 @@ Describe when this skill should be used.
3639
3894
  logger.log(` ${import_picocolors.default.dim("URL:")} Host the file, then ${import_picocolors.default.cyan(`npx synk add https://example.com/${displayPath}`)}`);
3640
3895
  logger.line();
3641
3896
  }
3642
- const AGENTS_DIR$1 = ".agents";
3643
- const LOCK_FILE$1 = ".skill-lock.json";
3644
- const CURRENT_LOCK_VERSION$1 = 4;
3645
- function getSkillLockPath$1() {
3646
- return join(homedir(), AGENTS_DIR$1, LOCK_FILE$1);
3647
- }
3648
- function readSkillLock$1() {
3649
- const lockPath = getSkillLockPath$1();
3650
- try {
3651
- const content = readFileSync(lockPath, "utf-8");
3652
- const parsed = JSON.parse(content);
3653
- if (typeof parsed.version !== "number" || !parsed.skills) return {
3654
- version: CURRENT_LOCK_VERSION$1,
3655
- skills: {}
3656
- };
3657
- if (parsed.version < CURRENT_LOCK_VERSION$1) return {
3658
- version: CURRENT_LOCK_VERSION$1,
3659
- skills: {}
3660
- };
3661
- return parsed;
3662
- } catch {
3663
- return {
3664
- version: CURRENT_LOCK_VERSION$1,
3665
- skills: {}
3666
- };
3667
- }
3668
- }
3669
3897
  async function runCheck(args = []) {
3670
- logger.log(`Checking for skill updates...`);
3898
+ logger.log("Checking for updates...");
3671
3899
  logger.line();
3672
- const lock = readSkillLock$1();
3673
- const skillNames = Object.keys(lock.skills);
3674
- if (skillNames.length === 0) {
3675
- logger.dim("No skills tracked in lock file.");
3676
- logger.log(`${import_picocolors.default.dim("Install skills with")} npx synk add <package>`);
3900
+ const lock = await readLockFile();
3901
+ const cognitiveNames = Object.keys(lock.cognitives);
3902
+ if (cognitiveNames.length === 0) {
3903
+ logger.dim("No cognitives tracked in lock file.");
3904
+ logger.log(`${import_picocolors.default.dim("Install cognitives with")} npx synk add <package>`);
3677
3905
  return;
3678
3906
  }
3679
3907
  const token = getGitHubToken();
3680
- const skillsBySource = /* @__PURE__ */ new Map();
3908
+ const cognitivesBySource = /* @__PURE__ */ new Map();
3681
3909
  let skippedCount = 0;
3682
- for (const skillName of skillNames) {
3683
- const entry = lock.skills[skillName];
3910
+ for (const name of cognitiveNames) {
3911
+ const entry = lock.cognitives[name];
3684
3912
  if (!entry) continue;
3685
- if (entry.sourceType !== "github" || !entry.skillFolderHash || !entry.skillPath) {
3913
+ if (entry.sourceType !== "github" || !entry.cognitiveFolderHash || !entry.cognitivePath) {
3686
3914
  skippedCount++;
3687
3915
  continue;
3688
3916
  }
3689
- const existing = skillsBySource.get(entry.source) || [];
3917
+ const existing = cognitivesBySource.get(entry.source) || [];
3690
3918
  existing.push({
3691
- name: skillName,
3919
+ name,
3692
3920
  entry
3693
3921
  });
3694
- skillsBySource.set(entry.source, existing);
3922
+ cognitivesBySource.set(entry.source, existing);
3695
3923
  }
3696
- const totalSkills = skillNames.length - skippedCount;
3697
- if (totalSkills === 0) {
3698
- logger.dim("No GitHub skills to check.");
3924
+ const totalCognitives = cognitiveNames.length - skippedCount;
3925
+ if (totalCognitives === 0) {
3926
+ logger.dim("No GitHub cognitives to check.");
3699
3927
  return;
3700
3928
  }
3701
- logger.dim(`Checking ${totalSkills} skill(s) for updates...`);
3929
+ logger.dim(`Checking ${totalCognitives} cognitive(s) for updates...`);
3702
3930
  const updates = [];
3703
3931
  const errors = [];
3704
- for (const [source, skills] of skillsBySource) for (const { name, entry } of skills) try {
3705
- const latestHash = await fetchSkillFolderHash(source, entry.skillPath, token);
3932
+ for (const [source, cognitives] of cognitivesBySource) for (const { name, entry } of cognitives) try {
3933
+ const latestHash = await fetchCognitiveFolderHash(source, entry.cognitivePath, token);
3706
3934
  if (!latestHash) {
3707
3935
  errors.push({
3708
3936
  name,
@@ -3711,7 +3939,7 @@ async function runCheck(args = []) {
3711
3939
  });
3712
3940
  continue;
3713
3941
  }
3714
- if (latestHash !== entry.skillFolderHash) updates.push({
3942
+ if (latestHash !== entry.cognitiveFolderHash) updates.push({
3715
3943
  name,
3716
3944
  source
3717
3945
  });
@@ -3723,7 +3951,7 @@ async function runCheck(args = []) {
3723
3951
  });
3724
3952
  }
3725
3953
  logger.line();
3726
- if (updates.length === 0) logger.success("All skills are up to date");
3954
+ if (updates.length === 0) logger.success("All cognitives are up to date");
3727
3955
  else {
3728
3956
  logger.log(`${updates.length} update(s) available:`);
3729
3957
  logger.line();
@@ -3732,75 +3960,48 @@ async function runCheck(args = []) {
3732
3960
  logger.dim(` source: ${update.source}`);
3733
3961
  }
3734
3962
  logger.line();
3735
- logger.log(`${import_picocolors.default.dim("Run")} npx synk update ${import_picocolors.default.dim("to update all skills")}`);
3963
+ logger.log(`${import_picocolors.default.dim("Run")} npx synk update ${import_picocolors.default.dim("to update all cognitives")}`);
3736
3964
  }
3737
3965
  if (errors.length > 0) {
3738
3966
  logger.line();
3739
- logger.dim(`Could not check ${errors.length} skill(s) (may need reinstall)`);
3967
+ logger.dim(`Could not check ${errors.length} cognitive(s) (may need reinstall)`);
3740
3968
  }
3741
3969
  track({
3742
3970
  event: "check",
3743
- skillCount: String(totalSkills),
3971
+ skillCount: String(totalCognitives),
3744
3972
  updatesAvailable: String(updates.length)
3745
3973
  });
3746
3974
  logger.line();
3747
3975
  }
3748
- const AGENTS_DIR = ".agents";
3749
- const LOCK_FILE = ".skill-lock.json";
3750
- const CURRENT_LOCK_VERSION = 4;
3751
- function getSkillLockPath() {
3752
- return join(homedir(), AGENTS_DIR, LOCK_FILE);
3753
- }
3754
- function readSkillLock() {
3755
- const lockPath = getSkillLockPath();
3756
- try {
3757
- const content = readFileSync(lockPath, "utf-8");
3758
- const parsed = JSON.parse(content);
3759
- if (typeof parsed.version !== "number" || !parsed.skills) return {
3760
- version: CURRENT_LOCK_VERSION,
3761
- skills: {}
3762
- };
3763
- if (parsed.version < CURRENT_LOCK_VERSION) return {
3764
- version: CURRENT_LOCK_VERSION,
3765
- skills: {}
3766
- };
3767
- return parsed;
3768
- } catch {
3769
- return {
3770
- version: CURRENT_LOCK_VERSION,
3771
- skills: {}
3772
- };
3773
- }
3774
- }
3775
3976
  async function runUpdate() {
3776
- logger.log("Checking for skill updates...");
3977
+ logger.log("Checking for updates...");
3777
3978
  logger.line();
3778
- const lock = readSkillLock();
3779
- const skillNames = Object.keys(lock.skills);
3780
- if (skillNames.length === 0) {
3781
- logger.dim("No skills tracked in lock file.");
3782
- logger.log(`${import_picocolors.default.dim("Install skills with")} npx synk add <package>`);
3979
+ const lock = await readLockFile();
3980
+ const cognitiveNames = Object.keys(lock.cognitives);
3981
+ if (cognitiveNames.length === 0) {
3982
+ logger.dim("No cognitives tracked in lock file.");
3983
+ logger.log(`${import_picocolors.default.dim("Install cognitives with")} npx synk add <package>`);
3783
3984
  return;
3784
3985
  }
3785
3986
  const token = getGitHubToken();
3786
3987
  const updates = [];
3787
3988
  let checkedCount = 0;
3788
- for (const skillName of skillNames) {
3789
- const entry = lock.skills[skillName];
3989
+ for (const name of cognitiveNames) {
3990
+ const entry = lock.cognitives[name];
3790
3991
  if (!entry) continue;
3791
- if (entry.sourceType !== "github" || !entry.skillFolderHash || !entry.skillPath) continue;
3992
+ if (entry.sourceType !== "github" || !entry.cognitiveFolderHash || !entry.cognitivePath) continue;
3792
3993
  checkedCount++;
3793
3994
  try {
3794
- const latestHash = await fetchSkillFolderHash(entry.source, entry.skillPath, token);
3795
- if (latestHash && latestHash !== entry.skillFolderHash) updates.push({
3796
- name: skillName,
3995
+ const latestHash = await fetchCognitiveFolderHash(entry.source, entry.cognitivePath, token);
3996
+ if (latestHash && latestHash !== entry.cognitiveFolderHash) updates.push({
3997
+ name,
3797
3998
  source: entry.source,
3798
3999
  entry
3799
4000
  });
3800
4001
  } catch {}
3801
4002
  }
3802
4003
  if (checkedCount === 0) {
3803
- logger.dim("No skills to check.");
4004
+ logger.dim("No cognitives to check.");
3804
4005
  return;
3805
4006
  }
3806
4007
  if (updates.length === 0) {
@@ -3815,17 +4016,22 @@ async function runUpdate() {
3815
4016
  for (const update of updates) {
3816
4017
  logger.log(`Updating ${update.name}...`);
3817
4018
  let installUrl = update.entry.sourceUrl;
3818
- if (update.entry.skillPath) {
3819
- let skillFolder = update.entry.skillPath;
3820
- if (skillFolder.endsWith("/SKILL.md")) skillFolder = skillFolder.slice(0, -9);
3821
- else if (skillFolder.endsWith("SKILL.md")) skillFolder = skillFolder.slice(0, -8);
4019
+ if (update.entry.cognitivePath) {
4020
+ let skillFolder = update.entry.cognitivePath;
4021
+ for (const fileName of Object.values(COGNITIVE_FILE_NAMES)) if (skillFolder.endsWith("/" + fileName)) {
4022
+ skillFolder = skillFolder.slice(0, -(fileName.length + 1));
4023
+ break;
4024
+ } else if (skillFolder.endsWith(fileName)) {
4025
+ skillFolder = skillFolder.slice(0, -fileName.length);
4026
+ break;
4027
+ }
3822
4028
  if (skillFolder.endsWith("/")) skillFolder = skillFolder.slice(0, -1);
3823
4029
  installUrl = update.entry.sourceUrl.replace(/\.git$/, "").replace(/\/$/, "");
3824
4030
  installUrl = `${installUrl}/tree/main/${skillFolder}`;
3825
4031
  }
3826
4032
  if (spawnSync("npx", [
3827
4033
  "-y",
3828
- "skills",
4034
+ "synk",
3829
4035
  "add",
3830
4036
  installUrl,
3831
4037
  "-g",
@@ -3843,8 +4049,8 @@ async function runUpdate() {
3843
4049
  }
3844
4050
  }
3845
4051
  logger.line();
3846
- if (successCount > 0) logger.success(`Updated ${successCount} skill(s)`);
3847
- if (failCount > 0) logger.dim(`Failed to update ${failCount} skill(s)`);
4052
+ if (successCount > 0) logger.success(`Updated ${successCount} cognitive(s)`);
4053
+ if (failCount > 0) logger.dim(`Failed to update ${failCount} cognitive(s)`);
3848
4054
  track({
3849
4055
  event: "update",
3850
4056
  skillCount: String(updates.length),