yarkr-cli 1.0.2 → 1.0.4

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 +26 -26
  2. package/dist/yarkr.js +59 -5
  3. package/package.json +2 -2
package/README.md CHANGED
@@ -1,41 +1,41 @@
1
- # yarkr
1
+ # yarkr-cli
2
2
 
3
3
  Install skills, agents and MCP toolsets from [Yarkr](https://yarkr.com) into the native layout of every harness you use:
4
4
  Claude Code, Codex, opencode, Cursor and more.
5
5
 
6
6
  ```sh
7
- npm install -g yarkr-cli # Node 22 or newer; or run any command with `npx yarkr-cli …`
8
- yarkr add posterus-ltd/code-review-checklist # a public package, no account needed
9
- yarkr add posterus-ltd/github --harness codex # pick the harnesses to write
7
+ npx yarkr-cli add posterus-ltd/code-review-checklist # a public package, no account needed (Node 22 or newer)
8
+ npx yarkr-cli add posterus-ltd/github --harness codex # pick the harnesses to write
10
9
  ```
11
10
 
12
11
  ## Sync an ark to your machine
13
12
 
14
- An ark is a curated set of skills, agents and toolsets hosted in the registry. `yarkr sync` writes each one into the
15
- harness's own layout (`~/.claude/skills/…`, `~/.agents/…`, MCP configs and so on):
13
+ An ark is a curated set of skills, agents and toolsets hosted in the registry. `npx yarkr-cli sync` writes each one into
14
+ the harness's own layout (`~/.claude/skills/…`, `~/.agents/…`, MCP configs and so on):
16
15
 
17
16
  ```sh
18
- yarkr arks # list public arks
19
- yarkr sync acme/starter # install one into this folder
20
- yarkr sync acme/starter -g # …or into your home directory
21
- yarkr sync acme/starter --harness claude-code # only write Claude Code's files
22
- yarkr ark # what your arks give you, and which version
17
+ npx yarkr-cli arks # list public arks
18
+ npx yarkr-cli sync acme/starter # install one into this folder
19
+ npx yarkr-cli sync acme/starter -g # …or into your home directory
20
+ npx yarkr-cli sync acme/starter --harness claude-code # only write Claude Code's files
21
+ npx yarkr-cli ark # what your arks give you, and which version
23
22
  ```
24
23
 
25
- Signed in, a bare `yarkr sync` installs every ark you're a member of, plus your personal ark. Run it again to pick up
26
- whatever an admin added or removed; `yarkr sync --check` exits 1 when you're behind.
24
+ Signed in, a bare `npx yarkr-cli sync` installs every ark you're a member of, plus your personal ark. Run it again to
25
+ pick up whatever an admin added or removed; `npx yarkr-cli sync --check` exits 1 when you're behind.
27
26
 
28
27
  ## Set up an existing repo
29
28
 
30
- In a project, `yarkr init` creates `yarkr.json` (and `.yarkrrc`), detecting the harnesses already used there.
31
- `yarkr add` and `yarkr sync` then pin every package in `yarkr.lock`, so teammates and CI get the same releases:
29
+ In a project, `npx yarkr-cli init` creates `yarkr.json` (and `.yarkrrc`), detecting the harnesses already used there.
30
+ `npx yarkr-cli add` and `npx yarkr-cli sync` then pin every package in `yarkr.lock`, so teammates and CI get the same
31
+ releases:
32
32
 
33
33
  ```sh
34
34
  cd my-repo
35
- yarkr init --ark acme/engineering # optional: install a team's ark into this project
36
- yarkr add posterus-ltd/playwright-test-authoring
35
+ npx yarkr-cli init --ark acme/engineering # optional: install a team's ark into this project
36
+ npx yarkr-cli add posterus-ltd/playwright-test-authoring
37
37
  git add yarkr.json yarkr.lock .yarkrrc .claude AGENTS.md && git commit
38
- yarkr sync --check # in CI: exit 1 when anything is out of date
38
+ npx yarkr-cli sync --check # in CI: exit 1 when anything is out of date
39
39
  ```
40
40
 
41
41
  To publish from the repo instead, there's nothing to init: Yarkr finds `SKILL.md` folders, `agents/*.md` and
@@ -43,9 +43,9 @@ To publish from the repo instead, there's nothing to init: Yarkr finds `SKILL.md
43
43
  SKILL.md) goes in one `yarkr.index.yaml` at the root, and nothing has to move. Lint it before you push:
44
44
 
45
45
  ```sh
46
- yarkr lint # what will be published, and what the hub would refuse
47
- yarkr lint --strict # in CI: fail on warnings too
48
- yarkr guide index-repo -o ~/.claude/skills/index-repo/ # a skill your agent uses to write the index
46
+ npx yarkr-cli lint # what will be published, and what the hub would refuse
47
+ npx yarkr-cli lint --strict # in CI: fail on warnings too
48
+ npx yarkr-cli guide index-repo -o ~/.claude/skills/index-repo/ # a skill your agent uses to write the index
49
49
  ```
50
50
 
51
51
  ## Sign in for private packages
@@ -53,12 +53,12 @@ yarkr guide index-repo -o ~/.claude/skills/index-repo/ # a skill your agent us
53
53
  Public packages and public arks work signed out. Your org's private packages and arks need a token:
54
54
 
55
55
  ```sh
56
- yarkr login # signs in in the browser; the token goes to your keychain (or ~/.yarkrrc)
57
- yarkr login --no-browser # over SSH: open the printed link anywhere, then paste the token
58
- yarkr whoami # check who you're signed in as
56
+ npx yarkr-cli login # signs in in the browser; the token goes to your keychain (or ~/.yarkrrc)
57
+ npx yarkr-cli login --no-browser # over SSH: open the printed link anywhere, then paste the token
58
+ npx yarkr-cli whoami # check who you're signed in as
59
59
  ```
60
60
 
61
- In CI, store a read-only token as a secret and set `YARKR_TOKEN`. `yarkr` uses the public hub at `https://yarkr.com`
62
- unless you point it at your own instance with `yarkr login --registry <url>`.
61
+ In CI, store a read-only token as a secret and set `YARKR_TOKEN`. The CLI uses the public hub at `https://yarkr.com`
62
+ unless you point it at your own instance with `npx yarkr-cli login --registry <url>`.
63
63
 
64
64
  Docs: [docs/cli.md](https://github.com/posterus-ltd/yarkr-public/blob/main/docs/cli.md) · Source: [github.com/posterus-ltd/yarkr-public](https://github.com/posterus-ltd/yarkr-public) · MIT
package/dist/yarkr.js CHANGED
@@ -39519,6 +39519,25 @@ var ConnectRepoBody = external_exports.object({
39519
39519
  classification: Classification.optional(),
39520
39520
  root_path: external_exports.string().max(200).optional()
39521
39521
  });
39522
+ var AddRepoBody = external_exports.object({
39523
+ /** `owner/repo` or a github.com URL. */
39524
+ repo: external_exports.string().trim().min(3).max(300),
39525
+ /** Only index below this folder, e.g. `skills` to skip a repo's templates and examples. */
39526
+ root_path: external_exports.string().max(200).optional()
39527
+ });
39528
+ var BulkAddReposBody = external_exports.object({
39529
+ /** `owner/repo` or github.com URLs; duplicates are added once. */
39530
+ repos: external_exports.array(external_exports.string().trim().min(1).max(300)).min(1).max(100),
39531
+ /** Applied to every repo added. */
39532
+ root_path: external_exports.string().max(200).optional()
39533
+ });
39534
+ var BanRepoBody = external_exports.object({ reason: external_exports.string().trim().min(1).max(500) });
39535
+ var IndexJobQuery = external_exports.object({
39536
+ status: external_exports.enum(["active", "queued", "running", "error", "done", "all"]).default("active"),
39537
+ /** Part of the repo's `owner/repo`, any case. */
39538
+ repo: external_exports.string().trim().max(200).optional(),
39539
+ limit: external_exports.coerce.number().int().min(1).max(500).default(200)
39540
+ });
39522
39541
  var AuditQuery = external_exports.object({
39523
39542
  package: external_exports.string().optional(),
39524
39543
  /** `me`: only what you did yourself. Anyone may read their own events. */
@@ -41349,13 +41368,23 @@ async function detectAssets(input2) {
41349
41368
  const byName = /* @__PURE__ */ new Map();
41350
41369
  for (const a of found.sort((x, y) => x.path.localeCompare(y.path))) {
41351
41370
  const prev = byName.get(a.name);
41352
- if (prev)
41353
- problems.push({ path: a.path, message: `Another asset is already named "${a.name}" (${prev.path}). Rename one of them in its frontmatter.` });
41354
- else
41371
+ if (!prev)
41355
41372
  byName.set(a.name, a);
41373
+ else if (!await sameFiles(prev, a, input2.read))
41374
+ problems.push({ path: a.path, message: `Another asset is already named "${a.name}" (${prev.path}) and its files differ. Rename one of them in its frontmatter, or make the copies identical.` });
41356
41375
  }
41357
41376
  return { assets: [...byName.values()], problems };
41358
41377
  }
41378
+ async function sameFiles(a, b, read) {
41379
+ if (a.kind !== b.kind || a.files.size !== b.files.size)
41380
+ return false;
41381
+ for (const [pkgPath, repoPath] of a.files) {
41382
+ const other = b.files.get(pkgPath);
41383
+ if (other === void 0 || await read(repoPath) !== await read(other))
41384
+ return false;
41385
+ }
41386
+ return true;
41387
+ }
41359
41388
  function toolsetServers2(text, path18, problems) {
41360
41389
  let doc;
41361
41390
  try {
@@ -45040,14 +45069,39 @@ async function repoLint(dir, opts) {
45040
45069
  return { assets, findings };
45041
45070
  }
45042
45071
 
45072
+ // src/banner.ts
45073
+ var WEBSITE = "https://yarkr.com";
45074
+ var WORDMARK = [
45075
+ "\u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588",
45076
+ " \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588",
45077
+ " \u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588",
45078
+ " \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588",
45079
+ " \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588"
45080
+ ];
45081
+ var rgb = (r, g, b) => (s) => kleur_default.enabled ? `\x1B[38;2;${r};${g};${b}m${s}\x1B[39m` : s;
45082
+ var petrol = rgb(74, 163, 191);
45083
+ function link(url2, text = url2) {
45084
+ return kleur_default.enabled ? `\x1B]8;;${url2}\x1B\\${text}\x1B]8;;\x1B\\` : text;
45085
+ }
45086
+ function banner(version2) {
45087
+ return [
45088
+ "",
45089
+ ...WORDMARK.map((l) => ` ${petrol(l)}`),
45090
+ "",
45091
+ ` ${kleur_default.bold("yarkr")} ${kleur_default.dim(`v${version2}`)} ${kleur_default.dim("\xB7")} skills, agents and MCP toolsets for every harness`,
45092
+ ` ${petrol("\u2192")} ${kleur_default.underline(petrol(link(WEBSITE)))}`,
45093
+ ""
45094
+ ].join("\n");
45095
+ }
45096
+
45043
45097
  // src/index.ts
45044
- var VERSION = true ? "1.0.2" : "0.0.0-dev";
45098
+ var VERSION = true ? "1.0.4" : "0.0.0-dev";
45045
45099
  var act = (fn) => async (...a) => {
45046
45100
  await fn(...a);
45047
45101
  };
45048
45102
  var syncFlags = (c) => c.option("--harness <ids...>", `limit to some harnesses (${HARNESS_IDS.join(", ")})`).option("--dry-run", "show what would change; write nothing").option("--check", "exit 1 if anything is out of date (for CI)").option("--force", "overwrite files edited locally").option("--require-signatures", "refuse unsigned releases").option("-g, --global", "install into your home directory instead of this folder").addOption(new Option("--user").hideHelp()).option("--registry <url>", "registry to use (default: from .yarkrrc)");
45049
45103
  function buildProgram() {
45050
- const program2 = new Command().name("yarkr").description("Yarkr: install your org's skills, agents and MCP configs into every harness.").version(VERSION).option("-q, --quiet", "only print warnings and errors").hook("preAction", (cmd) => {
45104
+ const program2 = new Command().name("yarkr").description("Yarkr: install your org's skills, agents and MCP configs into every harness.").version(VERSION).addHelpText("before", () => banner(VERSION)).option("-q, --quiet", "only print warnings and errors").hook("preAction", (cmd) => {
45051
45105
  ui.quiet = !!cmd.opts().quiet;
45052
45106
  });
45053
45107
  program2.command("login").description("sign in in the browser and keep a token in your keychain (or ~/.yarkrrc)").option("--registry <url>").option("--token <token>", "use this token instead of the browser (or pipe it on stdin)").option("--no-browser", "print a link to open on any device, then paste the token it shows").action(act(login));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "yarkr-cli",
3
- "version": "1.0.2",
3
+ "version": "1.0.4",
4
4
  "description": "Install skills, agents and MCP toolsets from Yarkr into Claude Code, Codex, opencode, Cursor and more",
5
5
  "license": "MIT",
6
6
  "homepage": "https://yarkr.com",
@@ -47,8 +47,8 @@
47
47
  "typescript": "~5.9.3",
48
48
  "vitest": "^3.2.4",
49
49
  "yaml": "^2.8.1",
50
- "@yarkr/evals": "0.1.0",
51
50
  "@yarkr/core": "0.1.0",
51
+ "@yarkr/evals": "0.1.0",
52
52
  "@yarkr/schema": "0.1.0"
53
53
  },
54
54
  "scripts": {