@ryuhq/sdk 0.1.10 → 0.1.12

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.
package/dist/cli.cjs CHANGED
@@ -1213,6 +1213,11 @@ function authToken() {
1213
1213
  return token;
1214
1214
  }
1215
1215
  var SDK_PUBLISH_KIND = "plugin";
1216
+ var VERSION_SHAPE = /^v?\d+(?:\.\d+){0,2}(?:-([0-9A-Za-z.-]+))?(?:\+[0-9A-Za-z.-]+)?$/;
1217
+ function channelOfVersion(version) {
1218
+ const first = VERSION_SHAPE.exec(version.trim())?.[1]?.split(".")[0];
1219
+ return first ? first.toLowerCase() : "stable";
1220
+ }
1216
1221
  async function commandPublish(rawDir) {
1217
1222
  const dir = (0, import_node_path.resolve)(rawDir);
1218
1223
  const manifest = loadManifest(dir);
@@ -1281,8 +1286,10 @@ async function commandPublish(rawDir) {
1281
1286
  if (!resp.ok) {
1282
1287
  exitError(`publish failed (${resp.status}): ${text}`);
1283
1288
  }
1289
+ const channel = channelOfVersion(manifest.version);
1290
+ const trainNote = channel === "stable" ? "" : ` on the \`${channel}\` channel (a prerelease train \u2014 users must select it)`;
1284
1291
  process.stdout.write(
1285
- `published ${manifest.id}@${manifest.version} (${kind}) \u2192 pending moderation
1292
+ `published ${manifest.id}@${manifest.version} (${kind})${trainNote} \u2192 pending moderation
1286
1293
  ${text}
1287
1294
  `
1288
1295
  );
package/dist/cli.js CHANGED
@@ -495,6 +495,11 @@ function authToken() {
495
495
  return token;
496
496
  }
497
497
  var SDK_PUBLISH_KIND = "plugin";
498
+ var VERSION_SHAPE = /^v?\d+(?:\.\d+){0,2}(?:-([0-9A-Za-z.-]+))?(?:\+[0-9A-Za-z.-]+)?$/;
499
+ function channelOfVersion(version) {
500
+ const first = VERSION_SHAPE.exec(version.trim())?.[1]?.split(".")[0];
501
+ return first ? first.toLowerCase() : "stable";
502
+ }
498
503
  async function commandPublish(rawDir) {
499
504
  const dir = resolve(rawDir);
500
505
  const manifest = loadManifest(dir);
@@ -563,8 +568,10 @@ async function commandPublish(rawDir) {
563
568
  if (!resp.ok) {
564
569
  exitError(`publish failed (${resp.status}): ${text}`);
565
570
  }
571
+ const channel = channelOfVersion(manifest.version);
572
+ const trainNote = channel === "stable" ? "" : ` on the \`${channel}\` channel (a prerelease train \u2014 users must select it)`;
566
573
  process.stdout.write(
567
- `published ${manifest.id}@${manifest.version} (${kind}) \u2192 pending moderation
574
+ `published ${manifest.id}@${manifest.version} (${kind})${trainNote} \u2192 pending moderation
568
575
  ${text}
569
576
  `
570
577
  );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ryuhq/sdk",
3
- "version": "0.1.10",
3
+ "version": "0.1.12",
4
4
  "type": "module",
5
5
  "description": "Ryu developer SDK: typed builders and CLI for authoring manifest.json Plugin bundles",
6
6
  "main": "./dist/index.cjs",
@@ -49,7 +49,7 @@
49
49
  "clean": "rm -rf dist"
50
50
  },
51
51
  "dependencies": {
52
- "@ryuhq/sdk-native": "0.1.10",
52
+ "@ryuhq/sdk-native": "0.1.12",
53
53
  "zod": "^4.1.13"
54
54
  },
55
55
  "devDependencies": {
package/src/cli.ts CHANGED
@@ -513,6 +513,24 @@ function authToken(): string {
513
513
  // uninstallable. Model / mcp items are published through their own tools.
514
514
  const SDK_PUBLISH_KIND = "plugin" as const;
515
515
 
516
+ /** Leading `x.y.z`, then the prerelease identifiers, then build metadata. */
517
+ const VERSION_SHAPE =
518
+ /^v?\d+(?:\.\d+){0,2}(?:-([0-9A-Za-z.-]+))?(?:\+[0-9A-Za-z.-]+)?$/;
519
+
520
+ /**
521
+ * The release channel a version publishes to: its first prerelease identifier
522
+ * lowercased, else `stable`.
523
+ *
524
+ * Mirrors the control plane's `deriveChannel` and Core's `channel_of` — the rule
525
+ * is that a version is self-describing, so this can only ever REPORT what the
526
+ * server will decide, never influence it. Anything unparseable reads as `stable`
527
+ * here; the server is the one that refuses it.
528
+ */
529
+ function channelOfVersion(version: string): string {
530
+ const first = VERSION_SHAPE.exec(version.trim())?.[1]?.split(".")[0];
531
+ return first ? first.toLowerCase() : "stable";
532
+ }
533
+
516
534
  async function commandPublish(rawDir: string): Promise<void> {
517
535
  const dir = resolve(rawDir);
518
536
  const manifest = loadManifest(dir);
@@ -616,8 +634,17 @@ async function commandPublish(rawDir: string): Promise<void> {
616
634
  if (!resp.ok) {
617
635
  exitError(`publish failed (${resp.status}): ${text}`);
618
636
  }
637
+ // Name the release channel the version landed on. It is DERIVED from the
638
+ // version (`1.5.0-beta.1` publishes to `beta`) and there is no flag to set it,
639
+ // so an author who did not mean to cut a prerelease finds out here rather than
640
+ // from a stable listing that never moved.
641
+ const channel = channelOfVersion(manifest.version);
642
+ const trainNote =
643
+ channel === "stable"
644
+ ? ""
645
+ : ` on the \`${channel}\` channel (a prerelease train — users must select it)`;
619
646
  process.stdout.write(
620
- `published ${manifest.id}@${manifest.version} (${kind}) → pending moderation\n${text}\n`
647
+ `published ${manifest.id}@${manifest.version} (${kind})${trainNote} → pending moderation\n${text}\n`
621
648
  );
622
649
  }
623
650
 
@@ -2143,6 +2143,28 @@ export interface ProvidesEntry {
2143
2143
  * forgets to declare it.
2144
2144
  */
2145
2145
  target?: ProviderTarget | null;
2146
+ /**
2147
+ * The human name of the **capability** (not of this provider): `"Search"` for
2148
+ * `web.search`, `"Document Parsing"` for `document.parse`. What a layer picker
2149
+ * puts above the provider list.
2150
+ *
2151
+ * Declared here, on the provider, because the capability itself is not a
2152
+ * manifest — it exists only as the string its providers agree on — and there is
2153
+ * nowhere else to hang the name. So every provider of a capability should carry
2154
+ * the same `title`, and the layer keeps its name when the default provider is
2155
+ * uninstalled.
2156
+ *
2157
+ * Deliberately NOT unanimity-checked the way [`Self::selectable`] is: forcing
2158
+ * six independent `web.search` manifests to spell one cosmetic string
2159
+ * byte-identically or fail to load trades a real capability for a label. Core
2160
+ * picks one with the same ladder the binder uses (declared default, else
2161
+ * lowest plugin id) and disagreement costs at most a differently-worded header.
2162
+ *
2163
+ * Absent = the client falls back to its own naming (a built-in table, else the
2164
+ * capability's last dotted segment). No server-side humaniser derives it from
2165
+ * the id — that route reads `news.crud` as "News Crud".
2166
+ */
2167
+ title?: string | null;
2146
2168
  /**
2147
2169
  * Capability **verb → this provider's tool** bindings, the seam that keeps the
2148
2170
  * model-visible tool surface stable across a swap.