@ichintansoni/skills-master 0.1.8 → 0.1.9

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 +39 -2
  2. package/dist/bin.js +86 -18
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -32,7 +32,7 @@ npx @ichintansoni/skills-master doctor # same detection,
32
32
  | GitHub Copilot | `.github/instructions/<name>.instructions.md` |
33
33
  | AGENTS.md | a sentinel-marked block (your hand-written content is preserved) |
34
34
 
35
- Flags: `--target claude,cursor,copilot,agents|all` · `--with-pairs` (also install the paired code↔design skill) · `--dry-run` · `--overwrite` · `--content <dir>` (use a local skills checkout) · `--ref <git-ref>`.
35
+ Flags: `--target claude,cursor,copilot,agents|all` · `--with-pairs` (also install the paired code↔design skill) · `--dry-run` · `--overwrite` · `--content <dir>` (use a local skills checkout) · `--ref <git-ref>`. An explicit `--target` or `--ref` is remembered in `skills-master.json`, and `--target` widens the configured set rather than replacing it.
36
36
 
37
37
  Claude Code users can alternatively install via the plugin marketplace:
38
38
 
@@ -41,8 +41,45 @@ Claude Code users can alternatively install via the plugin marketplace:
41
41
  /plugin install skills-master-apple-code@skills-master
42
42
  ```
43
43
 
44
+ ## Commands
45
+
46
+ Run `skills-master <command> --help` for the full flag list on any of these.
47
+
48
+ ### Browsing the catalog
49
+
50
+ | Command | What it does |
51
+ |---|---|
52
+ | `list` | List available skills. `--domain` · `--class` · `--category` · `--platform` · `--json` |
53
+ | `search <query>` | Match a query against names, descriptions, facets, and tags. Spacing, hyphens and case are ignored, so `wear os`, `wear-os` and `WearOS` all find the same skills. `--json` |
54
+ | `view <name>` | Show a skill's metadata and body. `--raw` prints the body alone; `--json` returns metadata *and* body in one document |
55
+
56
+ ### Working in a project
57
+
58
+ | Command | What it does |
59
+ |---|---|
60
+ | `init` | Detect which tools the project uses and write `skills-master.json`. `--target` · `--commit` · `--ref` · `--force` |
61
+ | `add <names…>` | Install skills by name, category, or class |
62
+ | `update [names…]` | Re-install skills whose **content** changed upstream. Only touches targets a skill is already installed to |
63
+ | `sync [names…]` | Re-emit to match the **current config** — new targets, moved `paths`, deleted files. `--overwrite` · `--prune` · `--dry-run` |
64
+ | `remove <names…>` | Remove installed skills. `--target` removes from one tool only |
65
+ | `status [names…]` | Inventory: versions, targets, and local-edit state. Offline, always exits 0. `--problems` · `--json` |
66
+ | `doctor` | The same detection as `status`, but **exits non-zero** on drift — the CI gate. `--json` |
67
+
68
+ `update` vs `sync` is the distinction worth knowing: `update` follows *content*, `sync` follows *config*.
69
+
70
+ ### Maintaining the library
71
+
72
+ These operate on a skills checkout rather than a consuming project.
73
+
74
+ | Command | What it does |
75
+ |---|---|
76
+ | `lint` | Validate the library: naming, reciprocal `pairs_with`, body caps, tag and source rules |
77
+ | `new <domain/class/category/name>` | Scaffold a skill from the canonical template. `--force` |
78
+ | `registry build` | Regenerate `registry.json`. `--check` fails on drift instead of rewriting |
79
+ | `marketplace build` | Regenerate the Claude plugin marketplace. `--check` fails on drift |
80
+
44
81
  ## How it works
45
82
 
46
83
  Content lives in the [skills-master repo](https://github.com/iChintanSoni/skills-master) and is fetched on demand; the CLI compiles each skill into your tools' formats and records what it installed in `skills-master.json` + a lockfile so `update`/`remove` stay surgical. Generated files are committed to your repo by default, so teammates' IDEs pick them up without running anything.
47
84
 
48
- MIT licensed. Skill content is original prose that summarizes Apple's publicly documented best practices and links to the canonical docs — it does not reproduce Apple's copyrighted text or sample code.
85
+ MIT licensed. Skill content is original prose that summarizes Apple's and Google's publicly documented best practices and links to the canonical docs — it does not reproduce either vendor's copyrighted text or sample code.
package/dist/bin.js CHANGED
@@ -4,7 +4,7 @@
4
4
  import { Command } from "commander";
5
5
 
6
6
  // package.json
7
- var version = "0.1.8";
7
+ var version = "0.1.9";
8
8
 
9
9
  // src/schema/projectConfig.ts
10
10
  import { z } from "zod";
@@ -1128,6 +1128,23 @@ async function addCommand(opts) {
1128
1128
  if (!hadConfig) {
1129
1129
  saveConfig(opts.cwd, { ...cfg, targets });
1130
1130
  log.info("Wrote skills-master.json.");
1131
+ } else {
1132
+ const merged = [.../* @__PURE__ */ new Set([...cfg.targets, ...opts.targets ?? []])].sort();
1133
+ const targetsChanged = opts.targets?.length != null && merged.join() !== [...cfg.targets].sort().join();
1134
+ const refChanged = opts.ref != null && opts.ref !== cfg.contentRef;
1135
+ if (targetsChanged || refChanged) {
1136
+ const next = {
1137
+ ...cfg,
1138
+ targets: targetsChanged ? merged : cfg.targets,
1139
+ contentRef: refChanged ? opts.ref : cfg.contentRef
1140
+ };
1141
+ saveConfig(opts.cwd, next);
1142
+ const what = [
1143
+ targetsChanged ? `targets: ${next.targets.join(", ")}` : null,
1144
+ refChanged ? `ref: ${next.contentRef}` : null
1145
+ ].filter(Boolean);
1146
+ log.info(`Updated skills-master.json (${what.join(", ")}).`);
1147
+ }
1131
1148
  }
1132
1149
  if (!cfg.commit) {
1133
1150
  ensureGitignored(
@@ -1306,16 +1323,34 @@ function doctorCommand(opts) {
1306
1323
  const problems = [];
1307
1324
  const note = (msg) => problems.push(msg);
1308
1325
  const cfg = loadConfig(opts.cwd);
1309
- if (!cfg) {
1310
- log.warn("No skills-master.json found \u2014 run `skills-master init`.");
1311
- } else {
1312
- log.info(`Config targets: ${cfg.targets.length ? cfg.targets.join(", ") : "(auto-detect)"}`);
1313
- }
1314
1326
  const lock = loadLockfile(opts.cwd);
1315
1327
  const diagnoses = diagnoseInstalled(opts.cwd, lock);
1328
+ const emit = (report) => {
1329
+ if (!opts.json) return report;
1330
+ log.plain(
1331
+ JSON.stringify(
1332
+ {
1333
+ ok: report.ok,
1334
+ problems: report.problems,
1335
+ skills: diagnoses,
1336
+ configuredTargets: cfg?.targets ?? []
1337
+ },
1338
+ null,
1339
+ 2
1340
+ )
1341
+ );
1342
+ return report;
1343
+ };
1344
+ if (!opts.json) {
1345
+ if (!cfg) {
1346
+ log.warn("No skills-master.json found \u2014 run `skills-master init`.");
1347
+ } else {
1348
+ log.info(`Config targets: ${cfg.targets.length ? cfg.targets.join(", ") : "(auto-detect)"}`);
1349
+ }
1350
+ }
1316
1351
  if (diagnoses.length === 0) {
1317
- log.info("No skills installed.");
1318
- return { problems, ok: true };
1352
+ if (!opts.json) log.info("No skills installed.");
1353
+ return emit({ problems, ok: true });
1319
1354
  }
1320
1355
  for (const skill of diagnoses) {
1321
1356
  for (const t of skill.targets) {
@@ -1332,14 +1367,16 @@ function doctorCommand(opts) {
1332
1367
  }
1333
1368
  }
1334
1369
  }
1335
- if (problems.length === 0) {
1336
- log.success(`All ${diagnoses.length} installed skill(s) look healthy.`);
1337
- } else {
1338
- for (const p of problems) log.warn(p);
1339
- log.plain(`
1370
+ if (!opts.json) {
1371
+ if (problems.length === 0) {
1372
+ log.success(`All ${diagnoses.length} installed skill(s) look healthy.`);
1373
+ } else {
1374
+ for (const p of problems) log.warn(p);
1375
+ log.plain(`
1340
1376
  ${problems.length} problem(s) found.`);
1377
+ }
1341
1378
  }
1342
- return { problems, ok: problems.length === 0 };
1379
+ return emit({ problems, ok: problems.length === 0 });
1343
1380
  }
1344
1381
 
1345
1382
  // src/commands/status.ts
@@ -1596,6 +1633,10 @@ async function searchCommand(opts) {
1596
1633
  [s.name, s.description, s.domain, s.category, s.class, ...s.tags].join(" ")
1597
1634
  ).includes(q)
1598
1635
  );
1636
+ if (opts.json) {
1637
+ log.plain(JSON.stringify(hits, null, 2));
1638
+ return hits;
1639
+ }
1599
1640
  if (hits.length === 0) {
1600
1641
  log.info(`No matches for "${opts.query}".`);
1601
1642
  return hits;
@@ -1612,6 +1653,24 @@ async function viewCommand(opts) {
1612
1653
  const content = await resolveContent({ content: opts.content, ref: opts.ref, cwd: opts.cwd });
1613
1654
  const skill = content.loadSkill(opts.name);
1614
1655
  const xm = skill.frontmatter["x-skills-master"];
1656
+ if (opts.json) {
1657
+ log.plain(
1658
+ JSON.stringify(
1659
+ {
1660
+ name: skill.name,
1661
+ description: skill.frontmatter.description,
1662
+ globs: skill.frontmatter.globs ?? [],
1663
+ tags: skill.frontmatter.tags ?? [],
1664
+ ...xm,
1665
+ resources: Object.entries(skill.resources).filter(([, v]) => v).map(([k]) => k),
1666
+ body: skill.body
1667
+ },
1668
+ null,
1669
+ 2
1670
+ )
1671
+ );
1672
+ return;
1673
+ }
1615
1674
  if (opts.raw) {
1616
1675
  log.plain(skill.body);
1617
1676
  return;
@@ -2118,15 +2177,24 @@ program.command("list").description("List available skills").option("--domain <d
2118
2177
  })
2119
2178
  )
2120
2179
  );
2121
- program.command("search <query>").description("Search skills by name, description, tags").option("--content <dir>", "local skills directory").option("--ref <ref>", "content git ref (tag/branch/sha)").action(
2122
- (query, opts) => run(() => searchCommand({ cwd: process.cwd(), query, content: opts.content, ref: opts.ref }))
2180
+ program.command("search <query>").description("Search skills by name, description, tags").option("--content <dir>", "local skills directory").option("--ref <ref>", "content git ref (tag/branch/sha)").option("--json", "machine-readable output").action(
2181
+ (query, opts) => run(
2182
+ () => searchCommand({
2183
+ cwd: process.cwd(),
2184
+ query,
2185
+ content: opts.content,
2186
+ ref: opts.ref,
2187
+ json: opts.json
2188
+ })
2189
+ )
2123
2190
  );
2124
- program.command("view <name>").description("Show a skill's metadata and body").option("--raw", "print the raw SKILL.md body").option("--content <dir>", "local skills directory").option("--ref <ref>", "content git ref (tag/branch/sha)").action(
2191
+ program.command("view <name>").description("Show a skill's metadata and body").option("--raw", "print the raw SKILL.md body").option("--content <dir>", "local skills directory").option("--ref <ref>", "content git ref (tag/branch/sha)").option("--json", "machine-readable output (metadata plus body)").action(
2125
2192
  (name, opts) => run(
2126
2193
  () => viewCommand({
2127
2194
  cwd: process.cwd(),
2128
2195
  name,
2129
2196
  raw: opts.raw,
2197
+ json: opts.json,
2130
2198
  content: opts.content,
2131
2199
  ref: opts.ref
2132
2200
  })
@@ -2191,7 +2259,7 @@ program.command("status").description("Show installed skills: versions, targets,
2191
2259
  })
2192
2260
  )
2193
2261
  );
2194
- program.command("doctor").description("Check installed skills for drift and missing files").action(() => run(() => doctorCommand({ cwd: process.cwd() }).ok, true));
2262
+ program.command("doctor").description("Check installed skills for drift and missing files").option("--json", "machine-readable output").action((opts) => run(() => doctorCommand({ cwd: process.cwd(), json: opts.json }).ok, true));
2195
2263
  program.command("lint").description("Validate the skill library (maintainer command)").option("--content <dir>", "local skills directory").action((opts) => run(() => lintCommand({ cwd: process.cwd(), content: opts.content }), true));
2196
2264
  program.command("new <spec>").description("Scaffold a new skill: domain/class/category/name (maintainer command)").option("--content <dir>", "local skills directory").option("--force", "overwrite an existing skill directory").action(
2197
2265
  (spec, opts) => run(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ichintansoni/skills-master",
3
- "version": "0.1.8",
3
+ "version": "0.1.9",
4
4
  "description": "Install tool-agnostic Apple & Android development skills into any AI coding tool (Claude Code, Cursor, Copilot, AGENTS.md).",
5
5
  "keywords": [
6
6
  "skills",