@rayul/kordis 0.10.3 → 0.11.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.
@@ -125,12 +125,19 @@ two parents requiring incompatible ranges = hard fail** (exit code
125
125
  can pin the offending one explicitly. Recommended deps are only
126
126
  walked at depth 0 when `--with-recommends` is passed.
127
127
 
128
+ **Per-version deps (0.11.0+)** — pinning an older version walks the
129
+ dependencies THAT version declared, not the package's current ones:
130
+ `kordis pull user/foo@0.1.0` resolves 0.1.0's graph even if newer
131
+ releases changed or dropped deps.
132
+
128
133
  `kordis read @range` resolves to a concrete version (the stderr footer
129
134
  shows it: `… @1.4.2 (resolved @^1 → 1.4.2)`) but does NOT walk
130
135
  transitive deps — read is a one-shot context inject, no install plan.
131
136
 
132
137
  `kordis info user/foo@^1` shows a `Requested: 1.4.2 (current: 2.0.0)`
133
- line above `Type` when the pin differs from the registry default.
138
+ line above `Type` when the pin differs from the registry default. Its
139
+ `Depends`/`Recommends` lists reflect the resolved version (0.11.0+), so
140
+ inspecting an old pin shows that version's declared deps.
134
141
 
135
142
  ## When a version is yanked (0.10.0+)
136
143
 
package/dist/index.js CHANGED
@@ -2379,30 +2379,13 @@ function searchCommand() {
2379
2379
  });
2380
2380
  }
2381
2381
  const queryProvided = query.length > 0;
2382
+ const emptyHint = opts.type ? `no packages of type "${opts.type}" match. Try without --type, or list everything: kordis search --type ${opts.type} --sort recent --limit 25` : queryProvided ? "try `--type skill` (or mcp-server / project-rules / custom-agent / hook) to narrow, or broader keywords" : 'try keywords (e.g. `kordis search "topic"`) or `kordis search --trending`';
2382
2383
  printDual({
2383
- json: res,
2384
+ json: res.results.length === 0 ? { ...res, hint: emptyHint } : res,
2384
2385
  human: () => {
2385
2386
  if (res.results.length === 0) {
2386
2387
  printHuman(c.yellow("(no results)"));
2387
- if (opts.type) {
2388
- printHuman(
2389
- c.gray(
2390
- ` \u2192 no packages of type "${opts.type}" match. Try without --type, or list everything: kordis search --type ${opts.type} --sort recent --limit 25`
2391
- )
2392
- );
2393
- } else if (queryProvided) {
2394
- printHuman(
2395
- c.gray(
2396
- " \u2192 try `--type skill` (or mcp-server / project-rules / custom-agent / hook) to narrow, or broader keywords"
2397
- )
2398
- );
2399
- } else {
2400
- printHuman(
2401
- c.gray(
2402
- ' \u2192 try keywords (e.g. `kordis search "topic"`) or `kordis search --trending`'
2403
- )
2404
- );
2405
- }
2388
+ printHuman(c.gray(` \u2192 ${emptyHint}`));
2406
2389
  return;
2407
2390
  }
2408
2391
  if (typeof res.total === "number") {
@@ -2523,7 +2506,7 @@ function normaliseDep(entry, idx) {
2523
2506
  }
2524
2507
  return {
2525
2508
  full_slug: m[1],
2526
- version_range: (m[3] ?? "*").trim()
2509
+ version_range: (m[4] ?? "*").trim()
2527
2510
  };
2528
2511
  }
2529
2512
  if (typeof entry === "object" && entry !== null) {
@@ -3798,28 +3781,44 @@ function parseUsername(raw) {
3798
3781
 
3799
3782
  // src/lib/parse-slug-version.ts
3800
3783
  var SUFFIX_CHARS = /[\^~*]/;
3784
+ function slugError(message, hint) {
3785
+ const e = new Error(message);
3786
+ e.hint = hint;
3787
+ return e;
3788
+ }
3801
3789
  function parseSlugAtVersion(raw) {
3802
3790
  if (!raw.includes("/")) {
3791
+ let username2;
3803
3792
  try {
3804
- const username2 = parseUsername(raw);
3805
- throw new Error(
3806
- `"${raw}" looks like a username, not a package \u2014 try \`kordis profile ${username2}\` for user details, or pass a full slug like "{username}/{slug}".`
3793
+ username2 = parseUsername(raw);
3794
+ } catch {
3795
+ username2 = void 0;
3796
+ }
3797
+ if (username2) {
3798
+ throw slugError(
3799
+ `"${raw}" looks like a username, not a package`,
3800
+ `Try \`kordis profile ${username2}\` for user details, or pass a full slug like "{username}/{slug}".`
3807
3801
  );
3808
- } catch (err) {
3809
- if (err instanceof Error) throw err;
3810
- throw new Error(`"${raw}" is missing the "{username}/{slug}" form`);
3811
3802
  }
3803
+ throw slugError(
3804
+ `"${raw}" is missing the "{username}/{slug}" form`,
3805
+ 'Use the form "{username}/{slug}", e.g. "alice/json-pretty".'
3806
+ );
3812
3807
  }
3813
3808
  const atIdx = raw.indexOf("@");
3814
3809
  const slugPart = atIdx === -1 ? raw : raw.slice(0, atIdx);
3815
3810
  const versionPart = atIdx === -1 ? "" : raw.slice(atIdx + 1);
3816
3811
  const [username, slug] = slugPart.split("/");
3817
3812
  if (!username || !slug) {
3818
- throw new Error('full_slug must be "{username}/{slug}"');
3813
+ throw slugError(
3814
+ 'full_slug must be "{username}/{slug}"',
3815
+ 'Pass both parts, e.g. "alice/json-pretty". Browse with `kordis search` if unsure.'
3816
+ );
3819
3817
  }
3820
3818
  if (atIdx !== -1 && versionPart.length === 0) {
3821
- throw new Error(
3822
- `"${raw}" has a trailing "@" with no version \u2014 drop the "@" or pass a version/range after it`
3819
+ throw slugError(
3820
+ `"${raw}" has a trailing "@" with no version`,
3821
+ `Drop the "@" or append a version/range, e.g. "${slugPart}@1.0.0" or "${slugPart}@^1".`
3823
3822
  );
3824
3823
  }
3825
3824
  const out = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rayul/kordis",
3
- "version": "0.10.3",
3
+ "version": "0.11.0",
4
4
  "private": false,
5
5
  "description": "Command-line client for the Kordis registry — discover, install, and publish agentic-coding packages.",
6
6
  "license": "MIT",