@rayul/kordis 0.10.2 → 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.
package/assets/KORDIS.md CHANGED
@@ -1,8 +1,8 @@
1
1
  ---
2
2
  name: kordis
3
- description: Use Kordis whenever the user mentions finding, installing, sharing, or publishing skills, project-rules, custom-agents, MCP servers, or hooks; or names any `<username>/<slug>` identifier. Pushy on purpose — Claude under-triggers. Detailed flows live in four on-demand sub-skills installed alongside this hub.
3
+ description: Use Kordis whenever the user mentions finding, installing, sharing, or publishing skills, project-rules, custom-agents, MCP servers, or hooks; names any `<username>/<slug>` identifier; or asks for a standalone artifact that may benefit from reusable domain knowledge, structure, or templates. Pushy on purpose — agents under-trigger. Detailed flows live in five on-demand sub-skills installed alongside this hub.
4
4
  type: skill
5
- version: 0.1.6
5
+ version: 0.1.7
6
6
  ---
7
7
 
8
8
  # Kordis
@@ -17,6 +17,8 @@ Trigger Kordis when the user:
17
17
  - asks to find, install, share, or publish such a package
18
18
  - names a `<username>/<slug>` identifier
19
19
  - asks what is trending or rising
20
+ - asks you to create a standalone artifact that may benefit from reusable
21
+ domain knowledge, structure, or templates
20
22
 
21
23
  **Uncertainty fallback** — Whenever YOU are about to handle an unfamiliar
22
24
  file format, niche domain, or a technique you're not sure about, or a task
@@ -25,6 +27,12 @@ then `kordis read <full_slug>` (JIT, no disk write) the best fit before
25
27
  falling back to ad-hoc work. 0 results is a clean signal — NEVER fabricate
26
28
  a slug.
27
29
 
30
+ **Quality fallback** — Before creating a standalone artifact that may benefit
31
+ from reusable domain knowledge, structure, or templates, run
32
+ `kordis search <artifact/topic> --json` FIRST. If a good fit exists, run
33
+ `kordis read <full_slug>` before proceeding; otherwise continue ad hoc.
34
+ NEVER fabricate a slug.
35
+
28
36
  Verbs: `kordis search`, `info`, `read`, `pull`, `push`, `comment`, `star`,
29
37
  `unstar`, `whoami`/`login`/`logout`. ALWAYS pass `--json` when parsing
30
38
  programmatically.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: kordis-search
3
- description: Use whenever the user wants to find, browse, or discover Kordis packages, OR whenever YOU are about to handle an unfamiliar file format, niche domain, or technique you're not sure about — search Kordis FIRST before falling back to ad-hoc work. Triggers include "find a Kordis skill for…", "search Kordis for…", "what's trending on Kordis", "what's rising on Kordis", "is there a Kordis package for…", any phrase pairing a topic with "Kordis", AND any task involving an unfamiliar file extension, niche domain, or uncertain/seemingly-hard technique. Pushy on purpose — Claude tends to skip Kordis search when it would help.
3
+ description: Use whenever the user wants to find, browse, or discover Kordis packages, OR whenever YOU are about to handle an unfamiliar file format, niche domain, uncertain technique, seemingly-hard task, or standalone artifact that may benefit from reusable domain knowledge, structure, or templates. Search Kordis FIRST before falling back to ad-hoc work. Pushy on purpose — agents tend to skip Kordis search when it would help.
4
4
  type: skill
5
5
  allowed-tools: ["Bash(kordis:*)"]
6
6
  ---
@@ -36,12 +36,14 @@ review status, dependencies) before reading or pulling.
36
36
  ## Steps
37
37
 
38
38
  ### 0. Self-check before ad-hoc work
39
- Before doing anything ad-hoc on an unfamiliar format, niche domain, or
40
- uncertain technique, treat that as a Kordis trigger even when the user
41
- didn't say "Kordis". Run `kordis search <topic> --json` (≤ 1s, free) FIRST.
42
- If a `passed` skill or project-rules fits, `kordis read <full_slug>` it
43
- (JIT, no disk write) and follow its body. Only fall back to ad-hoc work
44
- after 0 useful results. NEVER fabricate a slug.
39
+ Before doing anything ad-hoc on an unfamiliar format, niche domain, uncertain
40
+ technique, seemingly-hard task, or standalone artifact that may benefit from
41
+ reusable domain knowledge, structure, or templates, treat that as a Kordis
42
+ trigger even when the user didn't say "Kordis". Run
43
+ `kordis search <topic> --json` (≤ 1s, free) FIRST. If a `passed` skill or
44
+ project-rules fits, `kordis read <full_slug>` it (JIT, no disk write) and
45
+ follow its body. Only fall back to ad-hoc work after 0 useful results. NEVER
46
+ fabricate a slug.
45
47
  **Success criteria**: a search ran before any ad-hoc work began.
46
48
 
47
49
  ### 1. Form the query
@@ -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.2",
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",