skild 0.1.4 → 0.2.0

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 +5 -0
  2. package/dist/index.js +74 -16
  3. package/package.json +2 -2
package/README.md CHANGED
@@ -33,3 +33,8 @@ skild uninstall pdf -t codex --local
33
33
  # Create a new Skill
34
34
  skild init my-skill
35
35
  ```
36
+
37
+ Full user guide (CLI + registry + console):
38
+
39
+ - `docs/usage.md`
40
+ - `docs/usage.zh-CN.md`
package/dist/index.js CHANGED
@@ -7,7 +7,7 @@ import { createRequire } from "module";
7
7
 
8
8
  // src/commands/install.ts
9
9
  import chalk2 from "chalk";
10
- import { installRegistrySkill, installSkill, SkildError } from "@skild/core";
10
+ import { fetchWithTimeout, installRegistrySkill, installSkill, resolveRegistryUrl, SkildError } from "@skild/core";
11
11
 
12
12
  // src/utils/logger.ts
13
13
  import chalk from "chalk";
@@ -95,6 +95,7 @@ async function install(source, options = {}) {
95
95
  } else if (record.skill?.validation?.ok) {
96
96
  logger.installDetail(`Validation: ${chalk2.green("ok")}`);
97
97
  }
98
+ void reportDownload(record, options.registry);
98
99
  } catch (error) {
99
100
  spinner.fail(`Failed to install ${chalk2.red(source)}`);
100
101
  const message = error instanceof SkildError ? error.message : error instanceof Error ? error.message : String(error);
@@ -102,6 +103,36 @@ async function install(source, options = {}) {
102
103
  process.exitCode = 1;
103
104
  }
104
105
  }
106
+ async function reportDownload(record, registryOverride) {
107
+ try {
108
+ if (record.sourceType === "local") return;
109
+ const registryUrl = resolveRegistryUrl(record.registryUrl || registryOverride);
110
+ const endpoint = `${registryUrl}/stats/downloads`;
111
+ const payload = { source: "cli" };
112
+ if (record.sourceType === "registry") {
113
+ payload.entityType = "registry";
114
+ payload.entityId = record.canonicalName || record.source;
115
+ } else if (record.sourceType === "github-url") {
116
+ payload.entityType = "linked";
117
+ payload.sourceInput = { provider: "github", url: record.source };
118
+ } else if (record.sourceType === "degit-shorthand") {
119
+ payload.entityType = "linked";
120
+ payload.sourceInput = { provider: "github", spec: record.source };
121
+ } else {
122
+ return;
123
+ }
124
+ await fetchWithTimeout(
125
+ endpoint,
126
+ {
127
+ method: "POST",
128
+ headers: { "content-type": "application/json" },
129
+ body: JSON.stringify(payload)
130
+ },
131
+ 3e3
132
+ );
133
+ } catch {
134
+ }
135
+ }
105
136
 
106
137
  // src/commands/list.ts
107
138
  import chalk3 from "chalk";
@@ -298,7 +329,7 @@ async function init(name, options = {}) {
298
329
 
299
330
  // src/commands/signup.ts
300
331
  import chalk9 from "chalk";
301
- import { fetchWithTimeout, resolveRegistryUrl, SkildError as SkildError6 } from "@skild/core";
332
+ import { fetchWithTimeout as fetchWithTimeout2, resolveRegistryUrl as resolveRegistryUrl2, SkildError as SkildError6 } from "@skild/core";
302
333
 
303
334
  // src/utils/prompt.ts
304
335
  import readline from "readline";
@@ -332,7 +363,7 @@ async function promptPassword(question) {
332
363
 
333
364
  // src/commands/signup.ts
334
365
  async function signup(options) {
335
- const registry = resolveRegistryUrl(options.registry);
366
+ const registry = resolveRegistryUrl2(options.registry);
336
367
  const interactive = Boolean(process.stdin.isTTY && process.stdout.isTTY);
337
368
  const email = options.email?.trim() || "";
338
369
  const handle = options.handle?.trim() || "";
@@ -347,7 +378,7 @@ async function signup(options) {
347
378
  const finalPassword = password || await promptPassword("Password");
348
379
  let text = "";
349
380
  try {
350
- const res = await fetchWithTimeout(
381
+ const res = await fetchWithTimeout2(
351
382
  `${registry}/auth/signup`,
352
383
  {
353
384
  method: "POST",
@@ -377,14 +408,31 @@ async function signup(options) {
377
408
  return;
378
409
  }
379
410
  console.log(chalk9.green("Signup successful."));
411
+ try {
412
+ const parsed = JSON.parse(text);
413
+ if (parsed.verification?.requiredForPublish) {
414
+ if (parsed.verification.mode === "log") {
415
+ console.log(chalk9.dim("Dev mode: email sending is disabled. Check the registry dev logs for the verification link."));
416
+ } else if (parsed.verification.sent) {
417
+ console.log(chalk9.dim("Verification email sent. Check your inbox (and spam)."));
418
+ } else {
419
+ console.log(chalk9.yellow("Verification email was not sent. You may need to resend from the Console."));
420
+ }
421
+ console.log(chalk9.dim(`Verify/resend in Console: ${(parsed.verification.consoleUrl || "https://console.skild.sh").replace(/\/+$/, "")}/verify-email/request`));
422
+ } else if (parsed.verification) {
423
+ console.log(chalk9.dim("Email verification is recommended. Publishing may be restricted in the future."));
424
+ console.log(chalk9.dim(`Verify/resend in Console: ${(parsed.verification.consoleUrl || "https://console.skild.sh").replace(/\/+$/, "")}/verify-email/request`));
425
+ }
426
+ } catch {
427
+ }
380
428
  console.log(chalk9.dim("Next: run `skild login`"));
381
429
  }
382
430
 
383
431
  // src/commands/login.ts
384
432
  import chalk10 from "chalk";
385
- import { fetchWithTimeout as fetchWithTimeout2, resolveRegistryUrl as resolveRegistryUrl2, saveRegistryAuth, SkildError as SkildError7 } from "@skild/core";
433
+ import { fetchWithTimeout as fetchWithTimeout3, resolveRegistryUrl as resolveRegistryUrl3, saveRegistryAuth, SkildError as SkildError7 } from "@skild/core";
386
434
  async function login(options) {
387
- const registry = resolveRegistryUrl2(options.registry);
435
+ const registry = resolveRegistryUrl3(options.registry);
388
436
  const interactive = Boolean(process.stdin.isTTY && process.stdout.isTTY);
389
437
  const handleOrEmail = options.handleOrEmail?.trim() || "";
390
438
  const password = options.password || "";
@@ -398,7 +446,7 @@ async function login(options) {
398
446
  const finalTokenName = options.tokenName?.trim() || void 0;
399
447
  let text = "";
400
448
  try {
401
- const res = await fetchWithTimeout2(
449
+ const res = await fetchWithTimeout3(
402
450
  `${registry}/auth/login`,
403
451
  {
404
452
  method: "POST",
@@ -436,6 +484,10 @@ async function login(options) {
436
484
  return;
437
485
  }
438
486
  console.log(chalk10.green(`Logged in as ${chalk10.cyan(json.publisher.handle)}.`));
487
+ if (json.publisher.emailVerified === false) {
488
+ console.log(chalk10.yellow("Email not verified. Publishing may be restricted by server policy."));
489
+ console.log(chalk10.dim("Open the Publisher Console to verify: https://console.skild.sh/verify-email/request"));
490
+ }
439
491
  }
440
492
 
441
493
  // src/commands/logout.ts
@@ -448,7 +500,7 @@ async function logout() {
448
500
 
449
501
  // src/commands/whoami.ts
450
502
  import chalk12 from "chalk";
451
- import { fetchWithTimeout as fetchWithTimeout3, loadRegistryAuth, resolveRegistryUrl as resolveRegistryUrl3, SkildError as SkildError8 } from "@skild/core";
503
+ import { fetchWithTimeout as fetchWithTimeout4, loadRegistryAuth, resolveRegistryUrl as resolveRegistryUrl4, SkildError as SkildError8 } from "@skild/core";
452
504
  async function whoami() {
453
505
  const auth = loadRegistryAuth();
454
506
  if (!auth) {
@@ -456,9 +508,9 @@ async function whoami() {
456
508
  process.exitCode = 1;
457
509
  return;
458
510
  }
459
- const registryUrl = resolveRegistryUrl3(auth.registryUrl);
511
+ const registryUrl = resolveRegistryUrl4(auth.registryUrl);
460
512
  try {
461
- const res = await fetchWithTimeout3(
513
+ const res = await fetchWithTimeout4(
462
514
  `${registryUrl}/auth/me`,
463
515
  { headers: { authorization: `Bearer ${auth.token}`, accept: "application/json" } },
464
516
  5e3
@@ -486,7 +538,7 @@ import path from "path";
486
538
  import crypto from "crypto";
487
539
  import * as tar from "tar";
488
540
  import chalk13 from "chalk";
489
- import { fetchWithTimeout as fetchWithTimeout4, loadRegistryAuth as loadRegistryAuth2, resolveRegistryUrl as resolveRegistryUrl4, SkildError as SkildError9, splitCanonicalName, validateSkillDir } from "@skild/core";
541
+ import { fetchWithTimeout as fetchWithTimeout5, loadRegistryAuth as loadRegistryAuth2, resolveRegistryUrl as resolveRegistryUrl5, SkildError as SkildError9, splitCanonicalName, validateSkillDir } from "@skild/core";
490
542
  function sha256Hex(buf) {
491
543
  const h = crypto.createHash("sha256");
492
544
  h.update(buf);
@@ -498,7 +550,7 @@ function parseTargets(raw) {
498
550
  }
499
551
  async function publish(options = {}) {
500
552
  const auth = loadRegistryAuth2();
501
- const registry = resolveRegistryUrl4(options.registry || auth?.registryUrl);
553
+ const registry = resolveRegistryUrl5(options.registry || auth?.registryUrl);
502
554
  const token = auth?.token;
503
555
  if (!token) {
504
556
  console.error(chalk13.red("Not logged in. Run `skild login` first."));
@@ -531,7 +583,7 @@ async function publish(options = {}) {
531
583
  process.exitCode = 1;
532
584
  return;
533
585
  }
534
- const meRes = await fetchWithTimeout4(
586
+ const meRes = await fetchWithTimeout5(
535
587
  `${registry}/auth/me`,
536
588
  { headers: { authorization: `Bearer ${token}` } },
537
589
  1e4
@@ -584,7 +636,7 @@ async function publish(options = {}) {
584
636
  form.set("tag", tag);
585
637
  form.append("tarball", new Blob([buf], { type: "application/gzip" }), "skill.tgz");
586
638
  const { scope, name: skillName } = splitCanonicalName(name);
587
- const res = await fetchWithTimeout4(
639
+ const res = await fetchWithTimeout5(
588
640
  `${registry}/skills/${encodeURIComponent(scope)}/${encodeURIComponent(skillName)}/publish`,
589
641
  {
590
642
  method: "POST",
@@ -605,6 +657,12 @@ async function publish(options = {}) {
605
657
  return;
606
658
  }
607
659
  spinner.succeed(`Published ${chalk13.green(`${name}@${version2}`)} (sha256:${integrity.slice(0, 12)}\u2026)`);
660
+ try {
661
+ const parsed = JSON.parse(text);
662
+ const warnings = Array.isArray(parsed.warnings) ? parsed.warnings.map(String).filter(Boolean) : [];
663
+ for (const w of warnings) console.warn(chalk13.yellow(`Warning: ${w}`));
664
+ } catch {
665
+ }
608
666
  } catch (error) {
609
667
  spinner.fail("Publish failed");
610
668
  const message = error instanceof SkildError9 ? error.message : error instanceof Error ? error.message : String(error);
@@ -617,9 +675,9 @@ async function publish(options = {}) {
617
675
 
618
676
  // src/commands/search.ts
619
677
  import chalk14 from "chalk";
620
- import { resolveRegistryUrl as resolveRegistryUrl5, searchRegistrySkills, SkildError as SkildError10 } from "@skild/core";
678
+ import { resolveRegistryUrl as resolveRegistryUrl6, searchRegistrySkills, SkildError as SkildError10 } from "@skild/core";
621
679
  async function search(query, options = {}) {
622
- const registryUrl = resolveRegistryUrl5(options.registry);
680
+ const registryUrl = resolveRegistryUrl6(options.registry);
623
681
  const limit = Math.min(Math.max(Number.parseInt(options.limit || "50", 10) || 50, 1), 100);
624
682
  try {
625
683
  const skills = await searchRegistrySkills(registryUrl, query, limit);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "skild",
3
- "version": "0.1.4",
3
+ "version": "0.2.0",
4
4
  "description": "The npm for Agent Skills — Discover, install, manage, and publish AI Agent Skills with ease.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -37,7 +37,7 @@
37
37
  "commander": "^12.1.0",
38
38
  "ora": "^8.0.1",
39
39
  "tar": "^7.4.3",
40
- "@skild/core": "^0.1.4"
40
+ "@skild/core": "^0.2.0"
41
41
  },
42
42
  "devDependencies": {
43
43
  "@types/node": "^20.10.0",