skillstogether 0.1.0 → 0.1.2

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.
Files changed (3) hide show
  1. package/README.md +0 -13
  2. package/dist/index.js +370 -381
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -145,19 +145,6 @@ pnpm unlink --global
145
145
  node packages/cli/dist/index.js --help
146
146
  ```
147
147
 
148
- ### Environment Variables
149
-
150
- | Variable | Default | Description |
151
- | --------------------- | ----------------------- | -------------------- |
152
- | `CLI_API_URL` | `http://localhost:3000` | API server URL |
153
-
154
- Example:
155
-
156
- ```bash
157
- # Use a different API URL
158
- CLI_API_URL=http://localhost:3000 node dist/index.js auth login
159
- ```
160
-
161
148
  ### Testing the Full Flow
162
149
 
163
150
  1. Start the Next.js dev server:
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // src/index.ts
4
- import { Command as Command9 } from "commander";
4
+ import { Command as Command8 } from "commander";
5
5
 
6
6
  // src/commands/add.ts
7
7
  import * as p2 from "@clack/prompts";
@@ -49,16 +49,9 @@ function removeToken() {
49
49
  delete config.token;
50
50
  writeConfig(config);
51
51
  }
52
+ var API_URL = process.env.NODE_ENV === "production" ? "https://skillstogether.app" : "http://localhost:3000";
52
53
  function getApiUrl() {
53
- return process.env.CLI_API_URL || "http://localhost:3000";
54
- }
55
- function isInsecureApiUrl() {
56
- try {
57
- const parsed = new URL(getApiUrl());
58
- return parsed.protocol === "http:" && parsed.hostname !== "localhost" && parsed.hostname !== "127.0.0.1";
59
- } catch {
60
- return false;
61
- }
54
+ return API_URL;
62
55
  }
63
56
 
64
57
  // src/lib/constants.ts
@@ -174,20 +167,12 @@ async function fetchWithSizeLimit(url, options = {}) {
174
167
  }
175
168
 
176
169
  // src/lib/api.ts
177
- var insecureUrlWarned = false;
178
- function warnInsecureApiUrlOnce() {
179
- if (!insecureUrlWarned && isInsecureApiUrl()) {
180
- insecureUrlWarned = true;
181
- console.warn("Warning: CLI_API_URL is using HTTP. Use HTTPS in production.");
182
- }
183
- }
184
170
  function wrapFetchError(url, cause) {
185
171
  const message = cause instanceof Error ? cause.message : "Unknown network error";
186
172
  if (message === "fetch failed" || message.includes("ECONNREFUSED") || message.includes("ENOTFOUND") || message.includes("network")) {
187
- return new Error(
188
- `Cannot reach API at ${url}. Is the server running? Set CLI_API_URL if using a different host.`,
189
- { cause: cause instanceof Error ? cause : void 0 }
190
- );
173
+ return new Error(`Cannot reach API at ${url}.`, {
174
+ cause: cause instanceof Error ? cause : void 0
175
+ });
191
176
  }
192
177
  return cause instanceof Error ? cause : new Error(String(cause));
193
178
  }
@@ -196,7 +181,6 @@ async function apiGet(path, queryParams) {
196
181
  if (!token) {
197
182
  throw new Error("Not authenticated. Run 'auth login' first.");
198
183
  }
199
- warnInsecureApiUrlOnce();
200
184
  const apiUrl = getApiUrl();
201
185
  const url = new URL(`${apiUrl}/api${path}`);
202
186
  if (queryParams) {
@@ -230,7 +214,6 @@ async function apiPost(path, body) {
230
214
  if (!token) {
231
215
  throw new Error("Not authenticated. Run 'auth login' first.");
232
216
  }
233
- warnInsecureApiUrlOnce();
234
217
  const apiUrl = getApiUrl();
235
218
  const url = `${apiUrl}/api${path}`;
236
219
  let response;
@@ -517,23 +500,257 @@ import { basename, join as join3 } from "path";
517
500
 
518
501
  // src/lib/agents.ts
519
502
  var AGENTS = [
520
- { id: "cursor", name: "Cursor", dir: ".cursor/skills" },
521
- { id: "claude-code", name: "Claude Code", dir: ".claude/skills" },
522
- { id: "codex", name: "Codex", dir: ".codex/skills" },
523
- { id: "cline", name: "Cline", dir: ".cline/skills" },
524
- { id: "amp", name: "Amp", dir: ".agents/skills" },
525
- { id: "antigravity", name: "Antigravity", dir: ".agent/skills" },
526
- { id: "augment", name: "Augment", dir: ".augment/rules" },
527
- { id: "openclaw", name: "OpenClaw", dir: "skills" },
528
- { id: "codebuddy", name: "CodeBuddy", dir: ".codebuddy/skills" },
529
- { id: "windsurf", name: "Windsurf", dir: ".windsurf/skills" },
530
- { id: "goose", name: "Goose", dir: ".goose/skills" },
503
+ // A
504
+ {
505
+ id: "adal",
506
+ name: "AdaL",
507
+ dir: ".adal/skills",
508
+ globalDir: "~/.adal/skills"
509
+ },
510
+ {
511
+ id: "amp",
512
+ name: "Amp",
513
+ dir: ".agents/skills",
514
+ globalDir: "~/.config/agents/skills"
515
+ },
516
+ {
517
+ id: "antigravity",
518
+ name: "Antigravity",
519
+ dir: ".agent/skills",
520
+ globalDir: "~/.gemini/antigravity/skills"
521
+ },
522
+ {
523
+ id: "augment",
524
+ name: "Augment",
525
+ dir: ".augment/rules",
526
+ globalDir: "~/.augment/rules"
527
+ },
528
+ // C
529
+ {
530
+ id: "claude-code",
531
+ name: "Claude Code",
532
+ dir: ".claude/skills",
533
+ globalDir: "~/.claude/skills"
534
+ },
535
+ {
536
+ id: "cline",
537
+ name: "Cline",
538
+ dir: ".cline/skills",
539
+ globalDir: "~/.cline/skills"
540
+ },
541
+ {
542
+ id: "codebuddy",
543
+ name: "CodeBuddy",
544
+ dir: ".codebuddy/skills",
545
+ globalDir: "~/.codebuddy/skills"
546
+ },
547
+ {
548
+ id: "codex",
549
+ name: "Codex",
550
+ dir: ".codex/skills",
551
+ globalDir: "~/.codex/skills"
552
+ },
553
+ {
554
+ id: "command-code",
555
+ name: "Command Code",
556
+ dir: ".commandcode/skills",
557
+ globalDir: "~/.commandcode/skills"
558
+ },
559
+ {
560
+ id: "continue",
561
+ name: "Continue",
562
+ dir: ".continue/skills",
563
+ globalDir: "~/.continue/skills"
564
+ },
565
+ {
566
+ id: "crush",
567
+ name: "Crush",
568
+ dir: ".crush/skills",
569
+ globalDir: "~/.config/crush/skills"
570
+ },
571
+ {
572
+ id: "cursor",
573
+ name: "Cursor",
574
+ dir: ".cursor/skills",
575
+ globalDir: "~/.cursor/skills"
576
+ },
577
+ // D
578
+ {
579
+ id: "droid",
580
+ name: "Droid",
581
+ dir: ".factory/skills",
582
+ globalDir: "~/.factory/skills"
583
+ },
584
+ // G
585
+ {
586
+ id: "gemini-cli",
587
+ name: "Gemini CLI",
588
+ dir: ".gemini/skills",
589
+ globalDir: "~/.gemini/skills"
590
+ },
531
591
  {
532
592
  id: "github-copilot",
533
593
  name: "GitHub Copilot",
534
- dir: ".github/copilot/skills"
594
+ dir: ".github/skills",
595
+ globalDir: "~/.copilot/skills"
596
+ },
597
+ {
598
+ id: "goose",
599
+ name: "Goose",
600
+ dir: ".goose/skills",
601
+ globalDir: "~/.config/goose/skills"
602
+ },
603
+ // I
604
+ {
605
+ id: "iflow-cli",
606
+ name: "iFlow CLI",
607
+ dir: ".iflow/skills",
608
+ globalDir: "~/.iflow/skills"
609
+ },
610
+ // J
611
+ {
612
+ id: "junie",
613
+ name: "Junie",
614
+ dir: ".junie/skills",
615
+ globalDir: "~/.junie/skills"
616
+ },
617
+ // K
618
+ {
619
+ id: "kilo",
620
+ name: "Kilo Code",
621
+ dir: ".kilocode/skills",
622
+ globalDir: "~/.kilocode/skills"
623
+ },
624
+ {
625
+ id: "kimi-cli",
626
+ name: "Kimi Code CLI",
627
+ dir: ".agents/skills",
628
+ globalDir: "~/.config/agents/skills"
629
+ },
630
+ {
631
+ id: "kiro-cli",
632
+ name: "Kiro CLI",
633
+ dir: ".kiro/skills",
634
+ globalDir: "~/.kiro/skills"
635
+ },
636
+ {
637
+ id: "kode",
638
+ name: "Kode",
639
+ dir: ".kode/skills",
640
+ globalDir: "~/.kode/skills"
641
+ },
642
+ // M
643
+ {
644
+ id: "mcpjam",
645
+ name: "MCPJam",
646
+ dir: ".mcpjam/skills",
647
+ globalDir: "~/.mcpjam/skills"
648
+ },
649
+ {
650
+ id: "mistral-vibe",
651
+ name: "Mistral Vibe",
652
+ dir: ".vibe/skills",
653
+ globalDir: "~/.vibe/skills"
654
+ },
655
+ { id: "mux", name: "Mux", dir: ".mux/skills", globalDir: "~/.mux/skills" },
656
+ // N
657
+ {
658
+ id: "neovate",
659
+ name: "Neovate",
660
+ dir: ".neovate/skills",
661
+ globalDir: "~/.neovate/skills"
662
+ },
663
+ // O
664
+ {
665
+ id: "openclaw",
666
+ name: "OpenClaw",
667
+ dir: "skills",
668
+ globalDir: "~/.moltbot/skills"
669
+ },
670
+ {
671
+ id: "opencode",
672
+ name: "OpenCode",
673
+ dir: ".opencode/skills",
674
+ globalDir: "~/.config/opencode/skills"
675
+ },
676
+ {
677
+ id: "openhands",
678
+ name: "OpenHands",
679
+ dir: ".openhands/skills",
680
+ globalDir: "~/.openhands/skills"
681
+ },
682
+ // P
683
+ { id: "pi", name: "Pi", dir: ".pi/skills", globalDir: "~/.pi/agent/skills" },
684
+ {
685
+ id: "pochi",
686
+ name: "Pochi",
687
+ dir: ".pochi/skills",
688
+ globalDir: "~/.pochi/skills"
689
+ },
690
+ // Q
691
+ {
692
+ id: "qoder",
693
+ name: "Qoder",
694
+ dir: ".qoder/skills",
695
+ globalDir: "~/.qoder/skills"
696
+ },
697
+ {
698
+ id: "qwen-code",
699
+ name: "Qwen Code",
700
+ dir: ".qwen/skills",
701
+ globalDir: "~/.qwen/skills"
702
+ },
703
+ // R
704
+ {
705
+ id: "replit",
706
+ name: "Replit",
707
+ dir: ".agents/skills",
708
+ globalDir: null
709
+ // project-only
710
+ },
711
+ {
712
+ id: "roo",
713
+ name: "Roo Code",
714
+ dir: ".roo/skills",
715
+ globalDir: "~/.roo/skills"
716
+ },
717
+ // T
718
+ {
719
+ id: "trae",
720
+ name: "Trae",
721
+ dir: ".trae/skills",
722
+ globalDir: "~/.trae/skills"
723
+ },
724
+ {
725
+ id: "trae-cn",
726
+ name: "Trae CN",
727
+ dir: ".trae/skills",
728
+ globalDir: "~/.trae-cn/skills"
729
+ },
730
+ // W
731
+ {
732
+ id: "windsurf",
733
+ name: "Windsurf",
734
+ dir: ".windsurf/skills",
735
+ globalDir: "~/.codeium/windsurf/skills"
736
+ },
737
+ // Z
738
+ {
739
+ id: "zencoder",
740
+ name: "Zencoder",
741
+ dir: ".zencoder/skills",
742
+ globalDir: "~/.zencoder/skills"
535
743
  }
536
744
  ];
745
+ function getAgentsByIds(ids) {
746
+ return AGENTS.filter((agent) => ids.includes(agent.id));
747
+ }
748
+ function expandHomePath(path, homeDir) {
749
+ if (path.startsWith("~/")) {
750
+ return path.replace("~", homeDir);
751
+ }
752
+ return path;
753
+ }
537
754
 
538
755
  // src/lib/frontmatter.ts
539
756
  function parseFrontmatter(content) {
@@ -687,7 +904,7 @@ function scanAgentDirectory(agentDir, agent, scope) {
687
904
  function scanInstalledSkills(options = {}) {
688
905
  const skills = [];
689
906
  const projectDir = process.cwd();
690
- const globalDir = homedir2();
907
+ const homeDir = homedir2();
691
908
  const agentsToScan = options.agents ? AGENTS.filter((a) => options.agents.includes(a.id)) : AGENTS;
692
909
  for (const agent of agentsToScan) {
693
910
  if (!options.scope || options.scope === "project") {
@@ -699,8 +916,8 @@ function scanInstalledSkills(options = {}) {
699
916
  );
700
917
  skills.push(...projectSkills);
701
918
  }
702
- if (!options.scope || options.scope === "global") {
703
- const globalAgentDir = join3(globalDir, agent.dir);
919
+ if ((!options.scope || options.scope === "global") && agent.globalDir) {
920
+ const globalAgentDir = expandHomePath(agent.globalDir, homeDir);
704
921
  const globalSkills = scanAgentDirectory(globalAgentDir, agent, "global");
705
922
  skills.push(...globalSkills);
706
923
  }
@@ -832,7 +1049,19 @@ var SCOPE_CONFIGS = {
832
1049
  getBaseDir: () => homedir4()
833
1050
  }
834
1051
  };
835
- async function selectAgents(skipPrompts) {
1052
+ async function selectAgents(skipPrompts, targetAgents) {
1053
+ if (targetAgents) {
1054
+ const agentIds = targetAgents.split(",").map((id) => id.trim());
1055
+ const agents = getAgentsByIds(agentIds);
1056
+ if (agents.length === 0) {
1057
+ p.log.error(
1058
+ `No valid agents found for: ${agentIds.join(", ")}
1059
+ Available agents: ${AGENTS.map((a) => a.id).join(", ")}`
1060
+ );
1061
+ process.exit(1);
1062
+ }
1063
+ return agents;
1064
+ }
836
1065
  if (skipPrompts) {
837
1066
  return AGENTS.filter((a) => a.id === "cursor");
838
1067
  }
@@ -984,7 +1213,10 @@ function buildDownloadEvents(allResults, skills, scopeLabel) {
984
1213
  }
985
1214
  return events;
986
1215
  }
987
- var addCommand = new Command("add").description("Install skills from an organization").argument("<target>", "Organization slug or organization/skill slug").option("-d, --dir <path>", "Custom installation directory").option("-f, --force", "Overwrite existing skill files", false).option("-y, --yes", "Skip interactive prompts and install all skills", false).option("--skill <slug>", "Install a specific skill by slug").option("--global", "Install globally (in home directory)", false).action(
1216
+ var addCommand = new Command("add").description("Install skills from an organization").argument("<target>", "Organization slug or organization/skill slug").option("-d, --dir <path>", "Custom installation directory").option("-f, --force", "Overwrite existing skill files", false).option("-y, --yes", "Skip interactive prompts and install all skills", false).option("--skill <slug>", "Install a specific skill by slug").option("--global", "Install globally (in home directory)", false).option(
1217
+ "--target <agents>",
1218
+ "Comma-separated list of agent IDs to install to (e.g., claude-code,cursor)"
1219
+ ).action(
988
1220
  async (target, options) => {
989
1221
  printBanner();
990
1222
  p2.intro(pc3.bgCyan(pc3.black(" npx skillstogether ")));
@@ -1150,7 +1382,7 @@ async function installOrganizationSkills(organizationSlug, options) {
1150
1382
  );
1151
1383
  }
1152
1384
  }
1153
- const selectedAgents = await selectAgents(options.yes);
1385
+ const selectedAgents = await selectAgents(options.yes, options.target);
1154
1386
  if (!options.yes) {
1155
1387
  p2.log.step(
1156
1388
  `Selected ${pc3.green(selectedAgents.length.toString())} agent${selectedAgents.length > 1 ? "s" : ""}: ${selectedAgents.map((a) => a.name).join(", ")}`
@@ -1242,7 +1474,7 @@ async function installSingleSkill(organizationSlug, skillSlug, options) {
1242
1474
  if (skill.description) {
1243
1475
  p2.log.info(`Description: ${pc3.dim(skill.description)}`);
1244
1476
  }
1245
- const selectedAgents = await selectAgents(options.yes);
1477
+ const selectedAgents = await selectAgents(options.yes, options.target);
1246
1478
  if (!options.yes) {
1247
1479
  p2.log.step(
1248
1480
  `Selected ${pc3.green(selectedAgents.length.toString())} agent${selectedAgents.length > 1 ? "s" : ""}: ${selectedAgents.map((a) => a.name).join(", ")}`
@@ -1746,19 +1978,21 @@ var doctorCommand = new Command3("doctor").description("Diagnose and fix common
1746
1978
  message: `Configured: ${apiUrl}`
1747
1979
  });
1748
1980
  const projectDir = process.cwd();
1749
- const globalDir = homedir5();
1981
+ const homeDir = homedir5();
1750
1982
  let agentDirsFound = 0;
1751
1983
  const agentDirDetails = [];
1752
1984
  for (const agent of AGENTS) {
1753
1985
  const projectPath = join6(projectDir, agent.dir);
1754
- const globalPath = join6(globalDir, agent.dir);
1755
1986
  if (existsSync4(projectPath)) {
1756
1987
  agentDirsFound++;
1757
1988
  agentDirDetails.push(`${agent.name} (project): ${projectPath}`);
1758
1989
  }
1759
- if (existsSync4(globalPath)) {
1760
- agentDirsFound++;
1761
- agentDirDetails.push(`${agent.name} (global): ${globalPath}`);
1990
+ if (agent.globalDir) {
1991
+ const globalPath = expandHomePath(agent.globalDir, homeDir);
1992
+ if (existsSync4(globalPath)) {
1993
+ agentDirsFound++;
1994
+ agentDirDetails.push(`${agent.name} (global): ${globalPath}`);
1995
+ }
1762
1996
  }
1763
1997
  }
1764
1998
  if (agentDirsFound > 0) {
@@ -1917,7 +2151,7 @@ function displaySkillsByAgent(skills) {
1917
2151
  }
1918
2152
  }
1919
2153
  }
1920
- var listCommand = new Command4("list").description("List installed skills").option("--global", "Show only globally installed skills").option("--project", "Show only project-installed skills").option("--agent <id>", "Show only skills for a specific agent").option("--by-agent", "Group output by agent instead of organization").option("--json", "Output as JSON").action(
2154
+ var listCommand = new Command4("list").description("List installed skills").option("--global", "Show only globally installed skills").option("--project", "Show only project-installed skills").option("--agent <id>", "Show only skills for a specific agent").option("--by-agent", "Group output by agent instead of organization").action(
1921
2155
  async (options) => {
1922
2156
  printCompactBanner();
1923
2157
  p5.intro(pc6.bgCyan(pc6.black(" Installed Skills ")));
@@ -1947,26 +2181,6 @@ var listCommand = new Command4("list").description("List installed skills").opti
1947
2181
  p5.outro(pc6.dim("Done"));
1948
2182
  return;
1949
2183
  }
1950
- if (options.json) {
1951
- console.log(
1952
- JSON.stringify(
1953
- skills.map((s2) => ({
1954
- slug: s2.slug,
1955
- name: s2.name,
1956
- organization: s2.organization,
1957
- description: s2.description,
1958
- installedAt: s2.installedAt,
1959
- version: s2.version,
1960
- path: s2.path,
1961
- agent: s2.agent.id,
1962
- scope: s2.scope
1963
- })),
1964
- null,
1965
- 2
1966
- )
1967
- );
1968
- return;
1969
- }
1970
2184
  if (options.byAgent) {
1971
2185
  displaySkillsByAgent(skills);
1972
2186
  } else {
@@ -2016,7 +2230,7 @@ function groupByOrganization(skills) {
2016
2230
  }
2017
2231
  return groups;
2018
2232
  }
2019
- var statusCommand = new Command5("status").description("Check for skill updates").argument("[org-slug]", "Organization to check (optional)").option("--global", "Check only globally installed skills").option("--project", "Check only project-installed skills").option("--json", "Output as JSON").action(
2233
+ var statusCommand = new Command5("status").description("Check for skill updates").argument("[org-slug]", "Organization to check (optional)").option("--global", "Check only globally installed skills").option("--project", "Check only project-installed skills").action(
2020
2234
  async (organizationSlug, options) => {
2021
2235
  printCompactBanner();
2022
2236
  p6.intro(pc7.bgCyan(pc7.black(" Check for Updates ")));
@@ -2075,20 +2289,6 @@ var statusCommand = new Command5("status").description("Check for skill updates"
2075
2289
  const upToDateSkills = allUpdates.flatMap(
2076
2290
  (o) => o.updates.filter((u) => !u.hasUpdate)
2077
2291
  );
2078
- if (options.json) {
2079
- console.log(
2080
- JSON.stringify(
2081
- {
2082
- outdated: outdatedSkills,
2083
- upToDate: upToDateSkills,
2084
- errors
2085
- },
2086
- null,
2087
- 2
2088
- )
2089
- );
2090
- return;
2091
- }
2092
2292
  if (outdatedSkills.length > 0) {
2093
2293
  console.log();
2094
2294
  p6.log.warn(
@@ -2136,226 +2336,16 @@ var statusCommand = new Command5("status").description("Check for skill updates"
2136
2336
  }
2137
2337
  );
2138
2338
 
2139
- // src/commands/sync.ts
2339
+ // src/commands/uninstall.ts
2140
2340
  import * as p7 from "@clack/prompts";
2141
2341
  import { Command as Command6 } from "commander";
2142
- import { copyFileSync, existsSync as existsSync5, mkdirSync as mkdirSync3 } from "fs";
2143
- import { homedir as homedir6 } from "os";
2144
- import { dirname as dirname2, join as join7 } from "path";
2145
- import pc8 from "picocolors";
2146
- function getDestinationPath(skill, targetAgent, scope) {
2147
- const baseDir = scope === "global" ? homedir6() : process.cwd();
2148
- const folderName = SKILL_FOLDER_PATTERN(skill.organization, skill.slug);
2149
- return join7(baseDir, targetAgent.dir, folderName, SKILL_FILENAME);
2150
- }
2151
- function copySkill(sourcePath, destPath) {
2152
- try {
2153
- const destDir = dirname2(destPath);
2154
- if (!existsSync5(destDir)) {
2155
- mkdirSync3(destDir, { recursive: true });
2156
- }
2157
- copyFileSync(sourcePath, destPath);
2158
- return { success: true };
2159
- } catch (error) {
2160
- return {
2161
- success: false,
2162
- error: formatErrorMessage(error)
2163
- };
2164
- }
2165
- }
2166
- var syncCommand = new Command6("sync").description("Sync skills between agents").option("--from <agent>", "Source agent to sync from").option("--to <agent>", "Target agent to sync to (can be repeated)", []).option("--global", "Sync globally installed skills").option("--project", "Sync project-installed skills").option("-y, --yes", "Skip confirmation prompts").option("--dry-run", "Show what would be synced without making changes").action(
2167
- async (options) => {
2168
- printCompactBanner();
2169
- p7.intro(pc8.bgCyan(pc8.black(" Sync Skills ")));
2170
- let scope;
2171
- if (options.global && !options.project) {
2172
- scope = "global";
2173
- } else if (options.project && !options.global) {
2174
- scope = "project";
2175
- }
2176
- let sourceAgentId = options.from;
2177
- if (!sourceAgentId) {
2178
- const selected = await p7.select({
2179
- message: "Select source agent to sync from:",
2180
- options: AGENTS.map((agent) => ({
2181
- value: agent.id,
2182
- label: agent.name,
2183
- hint: agent.dir
2184
- }))
2185
- });
2186
- if (p7.isCancel(selected)) {
2187
- p7.cancel("Sync cancelled");
2188
- process.exit(0);
2189
- }
2190
- sourceAgentId = selected;
2191
- }
2192
- agentSchema.parse(sourceAgentId);
2193
- const sourceAgent = AGENTS.find((a) => a.id === sourceAgentId);
2194
- if (!sourceAgent) {
2195
- p7.log.error(`Unknown agent: ${sourceAgentId}`);
2196
- p7.log.info(`Available agents: ${AGENTS.map((a) => a.id).join(", ")}`);
2197
- p7.outro(pc8.red("Invalid agent"));
2198
- process.exit(1);
2199
- }
2200
- let targetAgentIds = options.to || [];
2201
- if (targetAgentIds.length === 0) {
2202
- const selected = await p7.multiselect({
2203
- message: "Select target agents to sync to:",
2204
- options: AGENTS.filter((a) => a.id !== sourceAgentId).map((agent) => ({
2205
- value: agent.id,
2206
- label: agent.name,
2207
- hint: agent.dir
2208
- })),
2209
- required: true
2210
- });
2211
- if (p7.isCancel(selected)) {
2212
- p7.cancel("Sync cancelled");
2213
- process.exit(0);
2214
- }
2215
- targetAgentIds = selected;
2216
- }
2217
- const targetAgents = [];
2218
- for (const id of targetAgentIds) {
2219
- agentSchema.parse(id);
2220
- const agent = AGENTS.find((a) => a.id === id);
2221
- if (!agent) {
2222
- p7.log.error(`Unknown agent: ${id}`);
2223
- p7.log.info(`Available agents: ${AGENTS.map((a) => a.id).join(", ")}`);
2224
- p7.outro(pc8.red("Invalid agent"));
2225
- process.exit(1);
2226
- }
2227
- if (agent.id === sourceAgentId) {
2228
- p7.log.warn(`Skipping source agent as target: ${id}`);
2229
- continue;
2230
- }
2231
- targetAgents.push(agent);
2232
- }
2233
- if (targetAgents.length === 0) {
2234
- p7.log.error("No valid target agents selected");
2235
- p7.outro(pc8.red("No targets"));
2236
- process.exit(1);
2237
- }
2238
- const s = p7.spinner();
2239
- s.start(`Scanning skills from ${pc8.cyan(sourceAgent.name)}...`);
2240
- const skills = scanInstalledSkills({
2241
- agents: [sourceAgentId],
2242
- scope
2243
- });
2244
- if (skills.length === 0) {
2245
- s.stop(`No skills found in ${pc8.cyan(sourceAgent.name)}`);
2246
- p7.outro(pc8.yellow("Nothing to sync"));
2247
- return;
2248
- }
2249
- s.stop(
2250
- `Found ${pc8.green(skills.length.toString())} skill${skills.length !== 1 ? "s" : ""} in ${pc8.cyan(sourceAgent.name)}`
2251
- );
2252
- const operations = [];
2253
- for (const skill of skills) {
2254
- for (const target of targetAgents) {
2255
- const destPath = getDestinationPath(skill, target, skill.scope);
2256
- const exists = existsSync5(destPath);
2257
- operations.push({
2258
- skill,
2259
- target,
2260
- destPath,
2261
- exists
2262
- });
2263
- }
2264
- }
2265
- console.log();
2266
- p7.log.info(
2267
- `Will sync ${pc8.green(skills.length.toString())} skill${skills.length !== 1 ? "s" : ""} to ${pc8.cyan(targetAgents.length.toString())} agent${targetAgents.length !== 1 ? "s" : ""}:`
2268
- );
2269
- for (const target of targetAgents) {
2270
- const targetOps = operations.filter((o) => o.target.id === target.id);
2271
- const targetNew = targetOps.filter((o) => !o.exists).length;
2272
- const targetUpdate = targetOps.filter((o) => o.exists).length;
2273
- console.log(` ${pc8.cyan(target.name)}`);
2274
- if (targetNew > 0) {
2275
- console.log(` ${pc8.green(`+ ${targetNew} new`)}`);
2276
- }
2277
- if (targetUpdate > 0) {
2278
- console.log(
2279
- ` ${pc8.yellow(`\u2191 ${targetUpdate} existing (will overwrite)`)}`
2280
- );
2281
- }
2282
- }
2283
- console.log();
2284
- if (options.dryRun) {
2285
- p7.log.info(pc8.dim("Dry run - no changes made"));
2286
- if (options.yes || await confirmVerbose()) {
2287
- for (const op of operations) {
2288
- const icon = op.exists ? pc8.yellow("\u2191") : pc8.green("+");
2289
- console.log(
2290
- ` ${icon} ${op.skill.organization}/${op.skill.slug} \u2192 ${op.target.name}`
2291
- );
2292
- console.log(` ${pc8.dim(shortenPath(op.destPath))}`);
2293
- }
2294
- }
2295
- p7.outro(pc8.dim("Done"));
2296
- return;
2297
- }
2298
- if (!options.yes) {
2299
- const confirmed = await p7.confirm({
2300
- message: `Sync ${skills.length} skill${skills.length !== 1 ? "s" : ""} to ${targetAgents.length} agent${targetAgents.length !== 1 ? "s" : ""}?`,
2301
- initialValue: true
2302
- });
2303
- if (p7.isCancel(confirmed) || !confirmed) {
2304
- p7.cancel("Sync cancelled");
2305
- process.exit(0);
2306
- }
2307
- }
2308
- const syncSpinner = p7.spinner();
2309
- syncSpinner.start("Syncing skills...");
2310
- let synced = 0;
2311
- let failed = 0;
2312
- const errors = [];
2313
- for (const op of operations) {
2314
- const result = copySkill(op.skill.path, op.destPath);
2315
- if (result.success) {
2316
- synced++;
2317
- } else {
2318
- failed++;
2319
- errors.push(
2320
- `${op.skill.organization}/${op.skill.slug} \u2192 ${op.target.name}: ${result.error}`
2321
- );
2322
- }
2323
- }
2324
- syncSpinner.stop("Sync complete");
2325
- if (synced > 0) {
2326
- p7.log.success(
2327
- `Synced ${pc8.green(synced.toString())} skill${synced !== 1 ? "s" : ""}`
2328
- );
2329
- }
2330
- if (failed > 0) {
2331
- p7.log.error(
2332
- `Failed to sync ${pc8.red(failed.toString())} skill${failed !== 1 ? "s" : ""}`
2333
- );
2334
- for (const error of errors) {
2335
- console.log(` ${pc8.red("\u2022")} ${error}`);
2336
- }
2337
- }
2338
- p7.outro(pc8.dim("Done"));
2339
- }
2340
- );
2341
- async function confirmVerbose() {
2342
- const showDetails = await p7.confirm({
2343
- message: "Show detailed operations?",
2344
- initialValue: false
2345
- });
2346
- return !p7.isCancel(showDetails) && showDetails;
2347
- }
2348
-
2349
- // src/commands/uninstall.ts
2350
- import * as p8 from "@clack/prompts";
2351
- import { Command as Command7 } from "commander";
2352
2342
  import { readdirSync as readdirSync2, rmSync, rmdirSync } from "fs";
2353
- import { dirname as dirname3 } from "path";
2354
- import pc9 from "picocolors";
2343
+ import { dirname as dirname2 } from "path";
2344
+ import pc8 from "picocolors";
2355
2345
  function removeSkill(skill) {
2356
2346
  try {
2357
2347
  rmSync(skill.path);
2358
- const orgDir = dirname3(skill.path);
2348
+ const orgDir = dirname2(skill.path);
2359
2349
  try {
2360
2350
  const remaining = readdirSync2(orgDir);
2361
2351
  if (remaining.length === 0) {
@@ -2371,10 +2361,10 @@ function removeSkill(skill) {
2371
2361
  };
2372
2362
  }
2373
2363
  }
2374
- var uninstallCommand = new Command7("uninstall").description("Remove installed skills").argument("<target>", "Organization slug or organization/skill slug").option("--all", "Remove all skills from the organization").option("--global", "Remove from global installation only").option("--project", "Remove from project installation only").option("-y, --yes", "Skip confirmation prompts").action(
2364
+ var uninstallCommand = new Command6("uninstall").description("Remove installed skills").argument("<target>", "Organization slug or organization/skill slug").option("--all", "Remove all skills from the organization").option("--global", "Remove from global installation only").option("--project", "Remove from project installation only").option("-y, --yes", "Skip confirmation prompts").action(
2375
2365
  async (target, options) => {
2376
2366
  printCompactBanner();
2377
- p8.intro(pc9.bgCyan(pc9.black(" Uninstall Skills ")));
2367
+ p7.intro(pc8.bgCyan(pc8.black(" Uninstall Skills ")));
2378
2368
  let scope;
2379
2369
  if (options.global && !options.project) {
2380
2370
  scope = "global";
@@ -2386,19 +2376,19 @@ var uninstallCommand = new Command7("uninstall").description("Remove installed s
2386
2376
  parsed = parseUninstallTarget(target);
2387
2377
  } catch (err) {
2388
2378
  const msg = err instanceof Error && "message" in err ? err.message : "Invalid target format";
2389
- p8.log.error(msg);
2390
- p8.outro(pc9.red("Invalid format"));
2379
+ p7.log.error(msg);
2380
+ p7.outro(pc8.red("Invalid format"));
2391
2381
  process.exit(1);
2392
2382
  }
2393
2383
  if (parsed.skillSlug === void 0) {
2394
2384
  if (!options.all) {
2395
- p8.log.error(
2396
- `To uninstall all skills from ${pc9.cyan(parsed.organizationSlug)}, use the ${pc9.cyan("--all")} flag`
2385
+ p7.log.error(
2386
+ `To uninstall all skills from ${pc8.cyan(parsed.organizationSlug)}, use the ${pc8.cyan("--all")} flag`
2397
2387
  );
2398
- p8.log.info(
2399
- `Or specify a skill: ${pc9.cyan(`npx skillstogether uninstall ${parsed.organizationSlug}/<skill-slug>`)}`
2388
+ p7.log.info(
2389
+ `Or specify a skill: ${pc8.cyan(`npx skillstogether uninstall ${parsed.organizationSlug}/<skill-slug>`)}`
2400
2390
  );
2401
- p8.outro(pc9.red("Aborted"));
2391
+ p7.outro(pc8.red("Aborted"));
2402
2392
  process.exit(1);
2403
2393
  }
2404
2394
  await uninstallOrganization(parsed.organizationSlug, scope, options.yes);
@@ -2413,37 +2403,37 @@ var uninstallCommand = new Command7("uninstall").description("Remove installed s
2413
2403
  }
2414
2404
  );
2415
2405
  async function uninstallOrganization(organizationSlug, scope, skipConfirm) {
2416
- const s = p8.spinner();
2417
- s.start(`Finding skills from ${pc9.cyan(organizationSlug)}...`);
2406
+ const s = p7.spinner();
2407
+ s.start(`Finding skills from ${pc8.cyan(organizationSlug)}...`);
2418
2408
  const skills = scanInstalledSkills({ organization: organizationSlug, scope });
2419
2409
  if (skills.length === 0) {
2420
- s.stop(`No skills found from ${pc9.cyan(organizationSlug)}`);
2421
- p8.outro(pc9.yellow("Nothing to uninstall"));
2410
+ s.stop(`No skills found from ${pc8.cyan(organizationSlug)}`);
2411
+ p7.outro(pc8.yellow("Nothing to uninstall"));
2422
2412
  return;
2423
2413
  }
2424
2414
  s.stop(
2425
- `Found ${pc9.green(skills.length.toString())} skill${skills.length !== 1 ? "s" : ""} from ${pc9.cyan(organizationSlug)}`
2415
+ `Found ${pc8.green(skills.length.toString())} skill${skills.length !== 1 ? "s" : ""} from ${pc8.cyan(organizationSlug)}`
2426
2416
  );
2427
2417
  console.log();
2428
- p8.log.info("Skills to remove:");
2418
+ p7.log.info("Skills to remove:");
2429
2419
  for (const skill of skills) {
2430
- const scopeBadge = skill.scope === "global" ? pc9.yellow("(global)") : pc9.dim("(project)");
2420
+ const scopeBadge = skill.scope === "global" ? pc8.yellow("(global)") : pc8.dim("(project)");
2431
2421
  console.log(
2432
- ` ${pc9.red("\u2022")} ${skill.name} ${pc9.dim(`[${skill.agent.name}]`)} ${scopeBadge}`
2422
+ ` ${pc8.red("\u2022")} ${skill.name} ${pc8.dim(`[${skill.agent.name}]`)} ${scopeBadge}`
2433
2423
  );
2434
2424
  }
2435
2425
  console.log();
2436
2426
  if (!skipConfirm) {
2437
- const confirmed = await p8.confirm({
2427
+ const confirmed = await p7.confirm({
2438
2428
  message: `Remove all ${skills.length} skill${skills.length !== 1 ? "s" : ""} from ${organizationSlug}?`,
2439
2429
  initialValue: false
2440
2430
  });
2441
- if (p8.isCancel(confirmed) || !confirmed) {
2442
- p8.cancel("Uninstall cancelled");
2431
+ if (p7.isCancel(confirmed) || !confirmed) {
2432
+ p7.cancel("Uninstall cancelled");
2443
2433
  process.exit(0);
2444
2434
  }
2445
2435
  }
2446
- const removeSpinner = p8.spinner();
2436
+ const removeSpinner = p7.spinner();
2447
2437
  removeSpinner.start("Removing skills...");
2448
2438
  let removed = 0;
2449
2439
  let failed = 0;
@@ -2459,53 +2449,53 @@ async function uninstallOrganization(organizationSlug, scope, skipConfirm) {
2459
2449
  }
2460
2450
  removeSpinner.stop("Removal complete");
2461
2451
  if (removed > 0) {
2462
- p8.log.success(
2463
- `Removed ${pc9.green(removed.toString())} skill${removed !== 1 ? "s" : ""}`
2452
+ p7.log.success(
2453
+ `Removed ${pc8.green(removed.toString())} skill${removed !== 1 ? "s" : ""}`
2464
2454
  );
2465
2455
  }
2466
2456
  if (failed > 0) {
2467
- p8.log.error(
2468
- `Failed to remove ${pc9.red(failed.toString())} skill${failed !== 1 ? "s" : ""}`
2457
+ p7.log.error(
2458
+ `Failed to remove ${pc8.red(failed.toString())} skill${failed !== 1 ? "s" : ""}`
2469
2459
  );
2470
2460
  for (const error of errors) {
2471
- p8.log.error(pc9.dim(` ${error}`));
2461
+ p7.log.error(pc8.dim(` ${error}`));
2472
2462
  }
2473
2463
  }
2474
- p8.outro(pc9.dim("Done"));
2464
+ p7.outro(pc8.dim("Done"));
2475
2465
  }
2476
2466
  async function uninstallSkill(organizationSlug, skillSlug, scope, skipConfirm) {
2477
- const s = p8.spinner();
2478
- s.start(`Finding ${pc9.cyan(`${organizationSlug}/${skillSlug}`)}...`);
2467
+ const s = p7.spinner();
2468
+ s.start(`Finding ${pc8.cyan(`${organizationSlug}/${skillSlug}`)}...`);
2479
2469
  const instances = findSkillInstances(organizationSlug, skillSlug, { scope });
2480
2470
  if (instances.length === 0) {
2481
- s.stop(`Skill ${pc9.cyan(`${organizationSlug}/${skillSlug}`)} not found`);
2482
- p8.outro(pc9.yellow("Nothing to uninstall"));
2471
+ s.stop(`Skill ${pc8.cyan(`${organizationSlug}/${skillSlug}`)} not found`);
2472
+ p7.outro(pc8.yellow("Nothing to uninstall"));
2483
2473
  return;
2484
2474
  }
2485
2475
  s.stop(
2486
- `Found ${pc9.green(instances.length.toString())} instance${instances.length !== 1 ? "s" : ""} of ${pc9.cyan(`${organizationSlug}/${skillSlug}`)}`
2476
+ `Found ${pc8.green(instances.length.toString())} instance${instances.length !== 1 ? "s" : ""} of ${pc8.cyan(`${organizationSlug}/${skillSlug}`)}`
2487
2477
  );
2488
2478
  console.log();
2489
- p8.log.info("Instances to remove:");
2479
+ p7.log.info("Instances to remove:");
2490
2480
  for (const skill of instances) {
2491
- const scopeBadge = skill.scope === "global" ? pc9.yellow("(global)") : pc9.dim("(project)");
2481
+ const scopeBadge = skill.scope === "global" ? pc8.yellow("(global)") : pc8.dim("(project)");
2492
2482
  console.log(
2493
- ` ${pc9.red("\u2022")} ${pc9.dim(`[${skill.agent.name}]`)} ${scopeBadge}`
2483
+ ` ${pc8.red("\u2022")} ${pc8.dim(`[${skill.agent.name}]`)} ${scopeBadge}`
2494
2484
  );
2495
- console.log(` ${pc9.dim(shortenPath(skill.path))}`);
2485
+ console.log(` ${pc8.dim(shortenPath(skill.path))}`);
2496
2486
  }
2497
2487
  console.log();
2498
2488
  if (!skipConfirm) {
2499
- const confirmed = await p8.confirm({
2489
+ const confirmed = await p7.confirm({
2500
2490
  message: `Remove ${instances.length} instance${instances.length !== 1 ? "s" : ""} of ${organizationSlug}/${skillSlug}?`,
2501
2491
  initialValue: false
2502
2492
  });
2503
- if (p8.isCancel(confirmed) || !confirmed) {
2504
- p8.cancel("Uninstall cancelled");
2493
+ if (p7.isCancel(confirmed) || !confirmed) {
2494
+ p7.cancel("Uninstall cancelled");
2505
2495
  process.exit(0);
2506
2496
  }
2507
2497
  }
2508
- const removeSpinner = p8.spinner();
2498
+ const removeSpinner = p7.spinner();
2509
2499
  removeSpinner.start("Removing skill...");
2510
2500
  let removed = 0;
2511
2501
  let failed = 0;
@@ -2521,26 +2511,26 @@ async function uninstallSkill(organizationSlug, skillSlug, scope, skipConfirm) {
2521
2511
  }
2522
2512
  removeSpinner.stop("Removal complete");
2523
2513
  if (removed > 0) {
2524
- p8.log.success(
2525
- `Removed ${pc9.green(removed.toString())} instance${removed !== 1 ? "s" : ""}`
2514
+ p7.log.success(
2515
+ `Removed ${pc8.green(removed.toString())} instance${removed !== 1 ? "s" : ""}`
2526
2516
  );
2527
2517
  }
2528
2518
  if (failed > 0) {
2529
- p8.log.error(
2530
- `Failed to remove ${pc9.red(failed.toString())} instance${failed !== 1 ? "s" : ""}`
2519
+ p7.log.error(
2520
+ `Failed to remove ${pc8.red(failed.toString())} instance${failed !== 1 ? "s" : ""}`
2531
2521
  );
2532
2522
  for (const error of errors) {
2533
- p8.log.error(pc9.dim(` ${error}`));
2523
+ p7.log.error(pc8.dim(` ${error}`));
2534
2524
  }
2535
2525
  }
2536
- p8.outro(pc9.dim("Done"));
2526
+ p7.outro(pc8.dim("Done"));
2537
2527
  }
2538
2528
 
2539
2529
  // src/commands/update.ts
2540
- import * as p9 from "@clack/prompts";
2541
- import { Command as Command8 } from "commander";
2530
+ import * as p8 from "@clack/prompts";
2531
+ import { Command as Command7 } from "commander";
2542
2532
  import { writeFileSync as writeFileSync3 } from "fs";
2543
- import pc10 from "picocolors";
2533
+ import pc9 from "picocolors";
2544
2534
  function generateUpdatedContent(skill, organizationSlug) {
2545
2535
  const frontmatter = generateFrontmatter({
2546
2536
  name: skill.name,
@@ -2552,16 +2542,16 @@ function generateUpdatedContent(skill, organizationSlug) {
2552
2542
  });
2553
2543
  return frontmatter + "\n" + (skill.content || "");
2554
2544
  }
2555
- var updateCommand = new Command8("update").description("Update installed skills to latest version").argument("[target]", "Organization slug or organization/skill slug").option("--global", "Update only globally installed skills").option("--project", "Update only project-installed skills").option("-y, --yes", "Skip confirmation prompts").option("--dry-run", "Show what would be updated without making changes").action(
2545
+ var updateCommand = new Command7("update").description("Update installed skills to latest version").argument("[target]", "Organization slug or organization/skill slug").option("--global", "Update only globally installed skills").option("--project", "Update only project-installed skills").option("-y, --yes", "Skip confirmation prompts").option("--dry-run", "Show what would be updated without making changes").action(
2556
2546
  async (target, options) => {
2557
2547
  printCompactBanner();
2558
- p9.intro(pc10.bgCyan(pc10.black(" Update Skills ")));
2548
+ p8.intro(pc9.bgCyan(pc9.black(" Update Skills ")));
2559
2549
  const token = getToken();
2560
2550
  if (!token) {
2561
- p9.log.error(
2562
- `Not authenticated. Run ${pc10.cyan("npx skillstogether auth login")} first.`
2551
+ p8.log.error(
2552
+ `Not authenticated. Run ${pc9.cyan("npx skillstogether auth login")} first.`
2563
2553
  );
2564
- p9.outro(pc10.red("Authentication required"));
2554
+ p8.outro(pc9.red("Authentication required"));
2565
2555
  process.exit(1);
2566
2556
  }
2567
2557
  let scope;
@@ -2579,12 +2569,12 @@ var updateCommand = new Command8("update").description("Update installed skills
2579
2569
  skillSlug = parsed.skillSlug;
2580
2570
  } catch (err) {
2581
2571
  const msg = err instanceof Error && "message" in err ? err.message : "Invalid target format";
2582
- p9.log.error(msg);
2583
- p9.outro(pc10.red("Invalid format"));
2572
+ p8.log.error(msg);
2573
+ p8.outro(pc9.red("Invalid format"));
2584
2574
  process.exit(1);
2585
2575
  }
2586
2576
  }
2587
- const s = p9.spinner();
2577
+ const s = p8.spinner();
2588
2578
  s.start("Scanning installed skills...");
2589
2579
  const allInstalledSkills = scanInstalledSkills({
2590
2580
  scope,
@@ -2596,15 +2586,15 @@ var updateCommand = new Command8("update").description("Update installed skills
2596
2586
  }
2597
2587
  if (skillsToCheck.length === 0) {
2598
2588
  s.stop("No installed skills found");
2599
- p9.log.info(
2600
- pc10.dim("Install skills with: npx skillstogether add <org-slug>")
2589
+ p8.log.info(
2590
+ pc9.dim("Install skills with: npx skillstogether add <org-slug>")
2601
2591
  );
2602
- p9.outro(pc10.dim("Done"));
2592
+ p8.outro(pc9.dim("Done"));
2603
2593
  return;
2604
2594
  }
2605
2595
  const uniqueSkills = deduplicateSkills(skillsToCheck);
2606
2596
  s.stop(
2607
- `Found ${pc10.green(uniqueSkills.length.toString())} installed skill${uniqueSkills.length !== 1 ? "s" : ""}`
2597
+ `Found ${pc9.green(uniqueSkills.length.toString())} installed skill${uniqueSkills.length !== 1 ? "s" : ""}`
2608
2598
  );
2609
2599
  const byOrg = /* @__PURE__ */ new Map();
2610
2600
  for (const skill of uniqueSkills) {
@@ -2612,7 +2602,7 @@ var updateCommand = new Command8("update").description("Update installed skills
2612
2602
  existing.push(skill);
2613
2603
  byOrg.set(skill.organization, existing);
2614
2604
  }
2615
- const checkSpinner = p9.spinner();
2605
+ const checkSpinner = p8.spinner();
2616
2606
  checkSpinner.start("Checking for updates...");
2617
2607
  const skillsToUpdate = [];
2618
2608
  const errors = [];
@@ -2641,17 +2631,17 @@ var updateCommand = new Command8("update").description("Update installed skills
2641
2631
  }
2642
2632
  checkSpinner.stop("Update check complete");
2643
2633
  if (skillsToUpdate.length === 0) {
2644
- p9.log.success("All skills are up to date!");
2634
+ p8.log.success("All skills are up to date!");
2645
2635
  if (errors.length > 0) {
2646
2636
  console.log();
2647
- p9.log.error(
2637
+ p8.log.error(
2648
2638
  `Failed to check ${errors.length} organization${errors.length !== 1 ? "s" : ""}:`
2649
2639
  );
2650
2640
  for (const error of errors) {
2651
- console.log(` ${pc10.red("\u2022")} ${error}`);
2641
+ console.log(` ${pc9.red("\u2022")} ${error}`);
2652
2642
  }
2653
2643
  }
2654
- p9.outro(pc10.dim("Done"));
2644
+ p8.outro(pc9.dim("Done"));
2655
2645
  return;
2656
2646
  }
2657
2647
  const totalInstances = skillsToUpdate.reduce(
@@ -2659,33 +2649,33 @@ var updateCommand = new Command8("update").description("Update installed skills
2659
2649
  0
2660
2650
  );
2661
2651
  console.log();
2662
- const updateMsg = skillsToUpdate.length === totalInstances ? `${pc10.yellow(skillsToUpdate.length.toString())} skill${skillsToUpdate.length !== 1 ? "s" : ""} will be updated:` : `${pc10.yellow(skillsToUpdate.length.toString())} skill${skillsToUpdate.length !== 1 ? "s" : ""} (${totalInstances} installations) will be updated:`;
2663
- p9.log.info(updateMsg);
2652
+ const updateMsg = skillsToUpdate.length === totalInstances ? `${pc9.yellow(skillsToUpdate.length.toString())} skill${skillsToUpdate.length !== 1 ? "s" : ""} will be updated:` : `${pc9.yellow(skillsToUpdate.length.toString())} skill${skillsToUpdate.length !== 1 ? "s" : ""} (${totalInstances} installations) will be updated:`;
2653
+ p8.log.info(updateMsg);
2664
2654
  for (const { unique, remoteVersion } of skillsToUpdate) {
2665
2655
  const agentNames = unique.agents.map((a) => a.name).join(", ");
2666
- const scopeBadge = unique.scope === "global" ? pc10.yellow("(global)") : pc10.dim("(project)");
2656
+ const scopeBadge = unique.scope === "global" ? pc9.yellow("(global)") : pc9.dim("(project)");
2667
2657
  console.log(
2668
- ` ${pc10.yellow("\u2191")} ${pc10.white(`${unique.organization}/${unique.slug}`)} ${pc10.dim(`v${unique.version || "?"}`)} \u2192 ${pc10.green(`v${remoteVersion}`)} ${pc10.dim(`[${agentNames}]`)} ${scopeBadge}`
2658
+ ` ${pc9.yellow("\u2191")} ${pc9.white(`${unique.organization}/${unique.slug}`)} ${pc9.dim(`v${unique.version || "?"}`)} \u2192 ${pc9.green(`v${remoteVersion}`)} ${pc9.dim(`[${agentNames}]`)} ${scopeBadge}`
2669
2659
  );
2670
2660
  }
2671
2661
  console.log();
2672
2662
  if (options.dryRun) {
2673
- p9.log.info(pc10.dim("Dry run - no changes made"));
2674
- p9.outro(pc10.dim("Done"));
2663
+ p8.log.info(pc9.dim("Dry run - no changes made"));
2664
+ p8.outro(pc9.dim("Done"));
2675
2665
  return;
2676
2666
  }
2677
2667
  if (!options.yes) {
2678
2668
  const confirmMsg = skillsToUpdate.length === totalInstances ? `Update ${skillsToUpdate.length} skill${skillsToUpdate.length !== 1 ? "s" : ""}?` : `Update ${skillsToUpdate.length} skill${skillsToUpdate.length !== 1 ? "s" : ""} (${totalInstances} installations)?`;
2679
- const confirmed = await p9.confirm({
2669
+ const confirmed = await p8.confirm({
2680
2670
  message: confirmMsg,
2681
2671
  initialValue: true
2682
2672
  });
2683
- if (p9.isCancel(confirmed) || !confirmed) {
2684
- p9.cancel("Update cancelled");
2673
+ if (p8.isCancel(confirmed) || !confirmed) {
2674
+ p8.cancel("Update cancelled");
2685
2675
  process.exit(0);
2686
2676
  }
2687
2677
  }
2688
- const updateSpinner = p9.spinner();
2678
+ const updateSpinner = p8.spinner();
2689
2679
  updateSpinner.start("Updating skills...");
2690
2680
  let updatedSkills = 0;
2691
2681
  let updatedInstances = 0;
@@ -2709,23 +2699,23 @@ var updateCommand = new Command8("update").description("Update installed skills
2709
2699
  }
2710
2700
  updateSpinner.stop("Update complete");
2711
2701
  if (updatedSkills > 0) {
2712
- const summaryMsg = updatedSkills === updatedInstances ? `Updated ${pc10.green(updatedSkills.toString())} skill${updatedSkills !== 1 ? "s" : ""}` : `Updated ${pc10.green(updatedSkills.toString())} skill${updatedSkills !== 1 ? "s" : ""} (${updatedInstances} installations)`;
2713
- p9.log.success(summaryMsg);
2702
+ const summaryMsg = updatedSkills === updatedInstances ? `Updated ${pc9.green(updatedSkills.toString())} skill${updatedSkills !== 1 ? "s" : ""}` : `Updated ${pc9.green(updatedSkills.toString())} skill${updatedSkills !== 1 ? "s" : ""} (${updatedInstances} installations)`;
2703
+ p8.log.success(summaryMsg);
2714
2704
  }
2715
2705
  if (failed > 0) {
2716
- p9.log.error(
2717
- `Failed to update ${pc10.red(failed.toString())} skill${failed !== 1 ? "s" : ""}`
2706
+ p8.log.error(
2707
+ `Failed to update ${pc9.red(failed.toString())} skill${failed !== 1 ? "s" : ""}`
2718
2708
  );
2719
2709
  for (const error of updateErrors) {
2720
- console.log(` ${pc10.red("\u2022")} ${error}`);
2710
+ console.log(` ${pc9.red("\u2022")} ${error}`);
2721
2711
  }
2722
2712
  }
2723
- p9.outro(pc10.dim("Done"));
2713
+ p8.outro(pc9.dim("Done"));
2724
2714
  }
2725
2715
  );
2726
2716
 
2727
2717
  // src/index.ts
2728
- var program = new Command9();
2718
+ var program = new Command8();
2729
2719
  program.name("skillstogether").description("CLI tool to install organization skills").version("0.1.0").hook("preAction", (thisCommand) => {
2730
2720
  const commandName = thisCommand.name();
2731
2721
  if (commandName === "skillstogether") {
@@ -2743,7 +2733,6 @@ program.addCommand(addCommand);
2743
2733
  program.addCommand(doctorCommand);
2744
2734
  program.addCommand(listCommand);
2745
2735
  program.addCommand(statusCommand);
2746
- program.addCommand(syncCommand);
2747
2736
  program.addCommand(uninstallCommand);
2748
2737
  program.addCommand(updateCommand);
2749
2738
  program.parse();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "skillstogether",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "CLI tool to install skills",
5
5
  "keywords": [
6
6
  "cli",