yeka-skills 0.2.1 → 0.2.3

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 +6 -3
  2. package/dist/cli.js +46 -13
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -31,8 +31,10 @@ yeka-skills logout
31
31
  ## Share a local skill with the team
32
32
 
33
33
  `yeka-skills share <skill>` packages one of your local skill folders and sends it to the private
34
- submission inbox, where a review bot turns it into a team-repo pull request. Nothing is published
35
- by a share a person reviews every submission first.
34
+ submission inbox, where the submission bot turns it into a team-repo pull request. Nothing bypasses
35
+ review but the reviewers are machines: the repository checks and an AI safety review gate the
36
+ merge, and they run from `main`, not from the pull request. The catalogue page was written from your
37
+ skill's own source and confirmed by you during the share conversation.
36
38
 
37
39
  - The CLI looks for the folder in the same local roots the installer knows. If a skill exists in
38
40
  several of them, it picks the one it would install into first (the current Codex folder, then
@@ -46,7 +48,8 @@ by a share — a person reviews every submission first.
46
48
  the review bot can find it, read it, and strip it before the skill content is unpacked. Do not
47
49
  create a `_yeka` folder inside your skill yourself.
48
50
  - A successful share answers with one sentence: the team is notified the moment the upload
49
- lands, and after review it usually goes live the same day, announced in #yeka-skills.
51
+ lands, and the skill goes live on its own once the automatic checks pass usually about ten
52
+ minutes — announced in #yeka-skills. A failed check messages the author, not the operator.
50
53
 
51
54
  Use `--dry-run` with `add`, `update`, or `remove` to verify and report changes without mutating the
52
55
  managed installation. Removal is fully offline and uses local receipts. It refuses locally edited
package/dist/cli.js CHANGED
@@ -2358,7 +2358,7 @@ var statusCommand = async (context = {}) => {
2358
2358
  return Promise.all(
2359
2359
  receipts.map((receipt) => inspectLocalStatus(receipt, remoteByName.get(receipt.skillName), home))
2360
2360
  );
2361
- });
2361
+ }, context.session);
2362
2362
  for (const status of statuses) {
2363
2363
  output(
2364
2364
  context,
@@ -2366,17 +2366,21 @@ var statusCommand = async (context = {}) => {
2366
2366
  );
2367
2367
  }
2368
2368
  };
2369
- var assertUpdatableStatuses = (skillName, statuses) => {
2369
+ var updateBlocker = (skillName, statuses) => {
2370
2370
  const modified = statuses.find((status) => status.kind === "modified");
2371
2371
  if (modified !== void 0) {
2372
- throw new CliError(
2373
- "local_changes",
2374
- `${skillName} has local changes for ${modified.receipt.runtime}. It was not changed.`
2375
- );
2372
+ return {
2373
+ code: "local_changes",
2374
+ message: `${skillName} has local changes for ${modified.receipt.runtime}. It was not changed.`
2375
+ };
2376
2376
  }
2377
2377
  if (statuses.some((status) => status.kind === "unavailable")) {
2378
- throw new CliError("skill_unavailable", `${skillName} is no longer available in the private registry.`);
2378
+ return {
2379
+ code: "skill_unavailable",
2380
+ message: `${skillName} is no longer available in the private registry.`
2381
+ };
2379
2382
  }
2383
+ return void 0;
2380
2384
  };
2381
2385
  var updateCommand = async (skillNameInput, options, context = {}) => {
2382
2386
  const selectedName = skillNameInput === void 0 ? void 0 : validatedSkillName(skillNameInput);
@@ -2396,17 +2400,25 @@ var updateCommand = async (skillNameInput, options, context = {}) => {
2396
2400
  const remoteByName = new Map(manifest.skills.map((skill) => [skill.name, skill]));
2397
2401
  const selectedGroups = [...groups.entries()].filter(([name]) => selectedName === void 0 || name === selectedName);
2398
2402
  const prepared = [];
2403
+ const skipped = [];
2399
2404
  for (const [name, receipts] of selectedGroups) {
2400
2405
  const remote = remoteByName.get(name);
2401
2406
  const statuses = await Promise.all(
2402
2407
  receipts.map((receipt) => inspectLocalStatus(receipt, remote, home))
2403
2408
  );
2404
- assertUpdatableStatuses(name, statuses);
2405
- if (remote === void 0) {
2406
- throw new CliError("skill_unavailable", `${name} is no longer available in the private registry.`);
2409
+ const blocker = updateBlocker(name, statuses) ?? (remote === void 0 ? { code: "skill_unavailable", message: `${name} is no longer available in the private registry.` } : void 0);
2410
+ if (blocker !== void 0) {
2411
+ if (selectedName !== void 0) {
2412
+ throw new CliError(blocker.code, blocker.message);
2413
+ }
2414
+ skipped.push(blocker.message);
2415
+ continue;
2407
2416
  }
2408
2417
  prepared.push({ name, receipts, skill: remote, statuses });
2409
2418
  }
2419
+ for (const message of skipped) {
2420
+ output(context, message);
2421
+ }
2410
2422
  const updated = [];
2411
2423
  for (const item of prepared) {
2412
2424
  if (item.statuses.every((status) => status.kind === "current")) {
@@ -2428,7 +2440,7 @@ var updateCommand = async (skillNameInput, options, context = {}) => {
2428
2440
  });
2429
2441
  }
2430
2442
  return updated;
2431
- });
2443
+ }, context.session);
2432
2444
  for (const result of results) {
2433
2445
  printActions(context, result.name, result.actions, options.dryRun === true);
2434
2446
  }
@@ -2496,6 +2508,23 @@ var shareCommand = async (skillNameInput, options, context = {}) => {
2496
2508
  const notes = options.notesFile === void 0 ? void 0 : await readNotesFile(options.notesFile);
2497
2509
  const check = await checkSkillFolder(folder.folderPath, skillName, void 0, notes);
2498
2510
  if (options.check === true) {
2511
+ try {
2512
+ const taken = await withRegistrySession(async (token) => {
2513
+ const manifest = await (context.client ?? new RegistryClient()).getManifest(token);
2514
+ return manifest.skills.some((skill) => skill.name === skillName);
2515
+ }, context.session);
2516
+ if (taken) {
2517
+ output(
2518
+ context,
2519
+ `The catalogue already has a skill called ${skillName}. If it is yours, sharing it now updates it. If it is not, rename your folder and its SKILL.md \`name:\` first, or the team's checks will turn it away.`
2520
+ );
2521
+ }
2522
+ } catch {
2523
+ output(
2524
+ context,
2525
+ "Could not reach the catalogue to see whether that name is free, so this only checked the folder."
2526
+ );
2527
+ }
2499
2528
  if (check.warnings.length === 0) {
2500
2529
  output(context, "Nothing looked risky.");
2501
2530
  } else {
@@ -2514,7 +2543,8 @@ var shareCommand = async (skillNameInput, options, context = {}) => {
2514
2543
  const client = context.client ?? new RegistryClient();
2515
2544
  try {
2516
2545
  await withRegistrySession(
2517
- (token) => client.uploadSubmission(skillName, packaged.sha256, packaged.bytes, token)
2546
+ (token) => client.uploadSubmission(skillName, packaged.sha256, packaged.bytes, token),
2547
+ context.session
2518
2548
  );
2519
2549
  } catch (error) {
2520
2550
  if (error instanceof CliError && error.code.startsWith("login_")) {
@@ -2525,7 +2555,10 @@ var shareCommand = async (skillNameInput, options, context = {}) => {
2525
2555
  }
2526
2556
  throw error;
2527
2557
  }
2528
- output(context, "Shared. The team was notified the moment it landed; after review it usually goes live the same day, announced in #yeka-skills.");
2558
+ output(
2559
+ context,
2560
+ "Shared. The team was notified the moment it landed. It goes live on its own once the automatic checks pass, usually about ten minutes, announced in #yeka-skills. If a check fails you get a Slack message saying what to fix."
2561
+ );
2529
2562
  };
2530
2563
  var loginCommand = async (context = {}) => {
2531
2564
  await deleteSession();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "yeka-skills",
3
- "version": "0.2.1",
3
+ "version": "0.2.3",
4
4
  "description": "Install, update, and remove private Gemography agent skills",
5
5
  "type": "module",
6
6
  "license": "UNLICENSED",