skillstogether 0.1.9 → 0.1.10

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 +27 -7
  2. package/dist/index.js +43 -9
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -3,12 +3,18 @@
3
3
  CLI tool to install organization skills from SkillsTogether.
4
4
 
5
5
  ```
6
- ███████╗██╗ ██╗██╗██╗ ██╗ ███████╗████████╗ ██████╗ ██████╗ ███████╗████████╗██╗ ██╗███████╗██████╗
7
- ██╔════╝██║ ██╔╝██║██║ ██║ ██╔════╝╚══██╔══╝██╔═══██╗██╔════╝ ██╔════╝╚══██╔══╝██║ ██║██╔════╝██╔══██╗
8
- ███████╗█████╔╝ ██║██║ ██║ ███████╗ ██║ ██║ ██║██║ ███╗█████╗ ██║ ███████║█████╗ ██████╔╝
9
- ╚════██║██╔═██╗ ██║██║ ██║ ╚════██║ ██║ ██║ ██║██║ ██║██╔══╝ ██║ ██╔══██║██╔══╝ ██╔══██╗
10
- ███████║██║ ██╗██║███████╗███████╗███████║ ██║ ╚██████╔╝╚██████╔╝███████╗ ██║ ██║ ██║███████╗██║ ██║
11
- ╚══════╝╚═╝ ╚═╝╚═╝╚══════╝╚══════╝╚══════╝ ╚═╝ ╚═════╝ ╚═════╝ ╚══════╝ ╚═╝ ╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝
6
+ ███████╗██╗ ██╗██╗██╗ ██╗ ███████╗
7
+ ██╔════╝██║ ██╔╝██║██║ ██║ ██╔════╝
8
+ ███████╗█████╔╝ ██║██║ ██║ ███████╗
9
+ ╚════██║██╔═██╗ ██║██║ ██║ ╚════██║
10
+ ███████║██║ ██╗██║███████╗███████╗███████║
11
+ ╚══════╝╚═╝ ╚═╝╚═╝╚══════╝╚══════╝╚══════╝
12
+ ████████╗ ██████╗ ██████╗ ███████╗████████╗██╗ ██╗███████╗██████╗
13
+ ╚══██╔══╝██╔═══██╗██╔════╝ ██╔════╝╚══██╔══╝██║ ██║██╔════╝██╔══██╗
14
+ ██║ ██║ ██║██║ ███╗█████╗ ██║ ███████║█████╗ ██████╔╝
15
+ ██║ ██║ ██║██║ ██║██╔══╝ ██║ ██╔══██║██╔══╝ ██╔══██╗
16
+ ██║ ╚██████╔╝╚██████╔╝███████╗ ██║ ██║ ██║███████╗██║ ██║
17
+ ╚═╝ ╚═════╝ ╚═════╝ ╚══════╝ ╚═╝ ╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝
12
18
  ```
13
19
 
14
20
  ## Installation
@@ -69,6 +75,20 @@ npx skillstogether uninstall <organization-slug> --skill <skill-slug>
69
75
 
70
76
  ```
71
77
 
78
+ ### Updating Skills
79
+
80
+ ```bash
81
+ # Update all installed skills
82
+ npx skillstogether update
83
+
84
+ # Update all skills from an organization
85
+ npx skillstogether update <organization-slug>
86
+
87
+ # Update a specific skill (skill slug already includes the org prefix)
88
+ npx skillstogether update <organization-slug> --skill <skill-slug>
89
+
90
+ ```
91
+
72
92
  ### Options
73
93
 
74
94
  | Option | Alias | Description |
@@ -76,7 +96,7 @@ npx skillstogether uninstall <organization-slug> --skill <skill-slug>
76
96
  | `--dir <path>` | `-d` | Custom installation directory |
77
97
  | `--force` | `-f` | Overwrite existing skill files |
78
98
  | `--yes` | `-y` | Skip interactive prompts, install all |
79
- | `--skill <slug>` | — | Install a specific skill by slug (org-prefixed) |
99
+ | `--skill <slug>` | — | Target a specific skill by slug (org-prefixed) |
80
100
  | `--global` | — | Install globally (in home directory) |
81
101
 
82
102
  ---
package/dist/index.js CHANGED
@@ -328,13 +328,23 @@ var addTargetSchema = z.string().min(1, "Target is required").refine(
328
328
  },
329
329
  { message: "Each part must be a valid slug (lowercase, numbers, hyphens)" }
330
330
  );
331
- var updateTargetSchema = z.string().max(200).optional().refine(
331
+ var updateTargetSchema = z.string().max(100).optional().refine(
332
332
  (val) => {
333
333
  if (!val) return true;
334
334
  const parts = val.split("/");
335
- return parts.length >= 1 && parts.length <= 2 && parts.every((part) => slugRegex.test(part));
335
+ return parts.length === 1;
336
+ },
337
+ {
338
+ message: "Target must be an organization slug (no '/'). Use --skill to target a specific skill."
339
+ }
340
+ ).refine(
341
+ (val) => {
342
+ if (!val) return true;
343
+ return slugRegex.test(val);
336
344
  },
337
- { message: "Target must be 'org-slug' or 'org-slug/skill-slug'" }
345
+ {
346
+ message: "Organization slug must be lowercase letters, numbers, and hyphens only"
347
+ }
338
348
  );
339
349
  var uninstallTargetSchema = z.string().min(1, "Target is required").refine(
340
350
  (val) => {
@@ -355,10 +365,9 @@ function parseUpdateTarget(target) {
355
365
  if (target === void 0 || target === "") return {};
356
366
  const parsed = updateTargetSchema.parse(target);
357
367
  if (!parsed || typeof parsed !== "string") return {};
358
- const parts = parsed.split("/");
368
+ const organizationSlug = organizationSlugSchema.parse(parsed);
359
369
  return {
360
- organizationSlug: parts[0],
361
- skillSlug: parts.length === 2 ? parts[1] : void 0
370
+ organizationSlug
362
371
  };
363
372
  }
364
373
  function parseUninstallTarget(target) {
@@ -2640,7 +2649,10 @@ function generateUpdatedContent(skill, organizationSlug) {
2640
2649
  });
2641
2650
  return frontmatter + "\n" + (skill.content || "");
2642
2651
  }
2643
- 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(
2652
+ var updateCommand = new Command8("update").description("Update installed skills to latest version").argument("[target]", "Organization slug").option("--global", "Update only globally installed skills").option("--project", "Update only project-installed skills").option(
2653
+ "--skill <slug>",
2654
+ "Update a specific skill by slug (already org-prefixed, e.g. acme-onboarding)"
2655
+ ).option("-y, --yes", "Skip confirmation prompts").option("--dry-run", "Show what would be updated without making changes").action(
2644
2656
  async (target, options) => {
2645
2657
  printCompactBanner();
2646
2658
  p9.intro(pc10.bgCyan(pc10.black(" Update Skills ")));
@@ -2659,12 +2671,10 @@ var updateCommand = new Command8("update").description("Update installed skills
2659
2671
  scope = "project";
2660
2672
  }
2661
2673
  let organizationSlug;
2662
- let skillSlug;
2663
2674
  if (target) {
2664
2675
  try {
2665
2676
  const parsed = parseUpdateTarget(target);
2666
2677
  organizationSlug = parsed.organizationSlug;
2667
- skillSlug = parsed.skillSlug;
2668
2678
  } catch (err) {
2669
2679
  const msg = err instanceof Error && "message" in err ? err.message : "Invalid target format";
2670
2680
  p9.log.error(msg);
@@ -2672,6 +2682,30 @@ var updateCommand = new Command8("update").description("Update installed skills
2672
2682
  process.exit(1);
2673
2683
  }
2674
2684
  }
2685
+ if (options.skill && !organizationSlug) {
2686
+ p9.log.error("Organization slug is required when using --skill");
2687
+ p9.outro(pc10.red("Invalid format"));
2688
+ process.exit(1);
2689
+ }
2690
+ let skillSlug;
2691
+ if (options.skill) {
2692
+ const skillResult = skillSlugSchema.safeParse(options.skill);
2693
+ if (!skillResult.success) {
2694
+ const msg = skillResult.error.issues?.[0]?.message ?? skillResult.error.message ?? "Invalid skill slug";
2695
+ p9.log.error(msg);
2696
+ p9.outro(pc10.red("Invalid format"));
2697
+ process.exit(1);
2698
+ }
2699
+ const expectedPrefix = `${organizationSlug}-`;
2700
+ if (!skillResult.data.startsWith(expectedPrefix)) {
2701
+ p9.log.error(
2702
+ `Skill slug must be prefixed with the organization slug (e.g., ${pc10.cyan(`${expectedPrefix}my-skill`)})`
2703
+ );
2704
+ p9.outro(pc10.red("Invalid format"));
2705
+ process.exit(1);
2706
+ }
2707
+ skillSlug = skillResult.data;
2708
+ }
2675
2709
  const s = p9.spinner();
2676
2710
  s.start("Scanning installed skills...");
2677
2711
  const allInstalledSkills = scanInstalledSkills({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "skillstogether",
3
- "version": "0.1.9",
3
+ "version": "0.1.10",
4
4
  "description": "CLI tool to install skills",
5
5
  "keywords": [
6
6
  "cli",