@rayul/kordis 0.1.8 → 0.1.10

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.
@@ -14,10 +14,18 @@ Publish a valid, AI-review-passing version. ALWAYS dry-run first.
14
14
  - `name` — must equal slug, lowercase-with-hyphens.
15
15
  - `description` — 1–2 sentences, slightly **pushy** ("Use whenever the
16
16
  user…"). Claude under-triggers without pushiness.
17
- - `version` — semver.
17
+ - `version` — semver. **Behaviour differs by path** (see below).
18
18
  - `license` — SPDX (e.g. `MIT`, `Apache-2.0`, `CC-BY-4.0`).
19
19
  - Optional: `homepage`, `tags`, `type`.
20
20
 
21
+ **`version` field handling:**
22
+ - **First publish** — used as-is (else defaults to `0.1.0`).
23
+ - **Update** — the registry computes the next version from
24
+ `current_version + --bump <strategy>` (default `patch`). If the file's
25
+ `version` differs from that result, the API rejects with `usage`. Either
26
+ drop the `version` field on updates, set `--bump` to match, or align
27
+ them.
28
+
21
29
  If the body contains third-party content, MUST preserve the original copyright
22
30
  and license text inside the body and link to source via `homepage`.
23
31
 
@@ -40,7 +48,14 @@ and license text inside the body and link to source via `homepage`.
40
48
 
41
49
  ### 1. Dry-run
42
50
  `kordis push <file> --dry-run --json`. Returns the same validation, conflict,
43
- and AI-review verdicts a real push would produce.
51
+ and version-resolution verdicts a real push would produce.
52
+
53
+ CAVEAT: dry-run does NOT exercise the AI reviewer — it short-circuits with
54
+ a synthetic `review.result: "passed"` (`prompt_version: "stub-v0"`). Treat
55
+ dry-run as syntactic + structural validation only. A real push routes
56
+ through the AI review worker, which can land terminal `passed` /
57
+ `rejected`, OR leave the publish in `status: "pending"` if the worker
58
+ hasn't decided within the wait window.
44
59
 
45
60
  **Success criteria**: dry-run returns a `status: "published"`-shaped envelope
46
61
  with no error flags.
@@ -51,7 +66,8 @@ Possible verdicts:
51
66
  - `conflict` (exit 40) — slug taken; suggest a different slug (or pass
52
67
  `--slug` if first publish).
53
68
  - `ai_review_rejected` (exit 32) — EXPLAIN the rejection to the user. Do NOT
54
- silently retry.
69
+ silently retry. Includes deterministic Stage-1 hits like
70
+ `curl_pipe_shell`, `aws_access_key`, `private_key_block`, etc.
55
71
  - `rate_limited` (exit 31) — wait `retry_after_seconds`.
56
72
  - `not_authenticated` (exit 10) — `kordis login`, then retry.
57
73
 
@@ -61,8 +77,12 @@ Possible verdicts:
61
77
  `kordis push <file> --json`. Add `--bump minor` (or `major`) when shipping a
62
78
  non-patch update.
63
79
 
64
- **Success criteria**: returns `{full_slug, version, url}`. Show all three to
65
- the user.
80
+ **Success criteria**: returns `{full_slug, version, url, status}`. Show all
81
+ four to the user. If `status: "pending"`, the AI reviewer hasn't decided
82
+ yet — re-check with `kordis info <full_slug> --json` (or wait and re-run
83
+ `kordis info`); the `pending` page is not yet served on the public URL.
84
+ If `status: "rejected"`, surface `review.flags` to the user and DO NOT
85
+ silently retry — explain why.
66
86
 
67
87
  ## Examples
68
88
 
@@ -76,7 +96,10 @@ User: "publish my new skill"
76
96
 
77
97
  <example>
78
98
  User: "release v0.2.0 of <full_slug>"
79
- 1. update `version: 0.2.0` in the file's frontmatter
99
+ - previous version was 0.1.x
100
+ 1. drop or align the frontmatter `version` field — `--bump minor` from
101
+ 0.1.x will yield 0.2.0; if the file says `0.2.0` that matches and is OK,
102
+ if it says anything else (e.g. `0.1.0`) the API will reject
80
103
  2. kordis push <file> --bump minor --dry-run --json
81
104
  3. clean → kordis push <file> --bump minor --json
82
105
  </example>
@@ -86,3 +109,25 @@ User: "release with a note that breaking-changes the API"
86
109
  1. kordis push <file> --bump major --changelog "BREAKING: <summary>" --dry-run --json
87
110
  2. clean → drop --dry-run for the real push
88
111
  </example>
112
+
113
+ ## Forking another Kordis package
114
+
115
+ When the user asks to fork / adapt / republish someone else's package
116
+ under their own slug, do the following:
117
+
118
+ 1. **License first.** Read the upstream `license` field (`kordis info
119
+ <upstream> --json`). MIT / Apache-2.0 / BSD all permit derivatives;
120
+ CC-BY-SA forces ShareAlike (your fork must use the same license).
121
+ GPL-flavoured / proprietary → STOP and tell the user.
122
+ 2. **Carry the legal minimum.** Preserve the upstream copyright and
123
+ permission notices verbatim inside the body. Do NOT strip them.
124
+ 3. **Credit upstream.** In the new package's body, add a `Derived from
125
+ <upstream-full-slug>` line near the top, and point `homepage` at the
126
+ upstream source (the original repo, not the Kordis page — `homepage`
127
+ is for the canonical authoring source).
128
+ 4. **Pick a fresh slug.** A fork is a *new* package; do not reuse the
129
+ upstream slug. Start at `0.1.0` (or whatever the file's `version` says
130
+ on first publish).
131
+ 5. **Tag derivation in `description`.** A short " — fork of
132
+ <upstream-full-slug>" suffix is enough; users searching the fork need
133
+ to know.
@@ -59,7 +59,15 @@ array.
59
59
  - For trending results, the `trending_score` field is populated — surface it
60
60
  when comparing.
61
61
  - IMPORTANT: if results are 0, RELAX one filter at a time before giving up.
62
- Do NOT invent a slug to fill the gap.
62
+ **Drop `--tool` first** — many published packages have an empty
63
+ `tools_compatible` field, so `--tool <name>` undercounts hard. Then drop
64
+ `--type`. Then shorten the query. Do NOT invent a slug to fill the gap.
65
+ - Most packages on the registry are very young — `stars` and `downloads` are
66
+ often `0`. Lean on `review_status: passed` and the description text match,
67
+ not on social signals alone.
68
+ - For richer triage data, prefer `kordis search --json` over
69
+ `kordis info --json` — search returns `description`, `tier`,
70
+ `review_status`, `tools_compatible`, etc. per result; `info` is sparser.
63
71
  - Surface the top 3–5 with slug, type, tier, stars, one-line description.
64
72
 
65
73
  **Success criteria**: user picked one, or you reported "no fit" honestly.
@@ -34,15 +34,30 @@ Post a top-level comment on a package. Auth required.
34
34
  | `--kind <k>` | `comment` (default), `tip`, `report`, `praise`, `question` |
35
35
  | `--title <t>` | 1–140 chars; honoured for top-level posts only |
36
36
 
37
- Replies, edits, status flips (open/resolved on a `report`), and listing
38
- existing comments are NOT yet exposed in the CLI. Direct the user to
39
- `https://kordis.store/p/<full_slug>` for those interactions until verbs land.
37
+ **Pick the right `--kind`:**
38
+ - `comment` — generic remark, default when nothing more specific fits.
39
+ - `tip` — actionable advice for OTHER users ("works great if you also
40
+ pull <other-slug>"). Subject of the post is reader, not author.
41
+ - `report` — bug / problem report. Has an open/resolved status (managed on
42
+ the web today).
43
+ - `praise` — short thank-you / compliment to the author. Body is enough;
44
+ `--title` is optional.
45
+ - `question` — explicit question expecting a reply (typically from the
46
+ author). Use when the user wants a response, not just to share thought.
47
+
48
+ Replies, edits, status flips (open/resolved on a `report`), listing
49
+ existing comments, and reading back your own comments are NOT yet exposed
50
+ in the CLI. Direct the user to `https://kordis.store/p/<full_slug>` for
51
+ those interactions until verbs land.
40
52
 
41
53
  ## Star commands
42
54
 
43
55
  ### `kordis star <full_slug> [--json]`
44
56
  Mark a package as a favourite. Idempotent — re-running on an already-starred
45
- package returns the current count without a duplicate. Auth required.
57
+ package returns the current count without a duplicate. Auth required. The
58
+ response shape is the same whether the call newly starred or no-op'd; if the
59
+ user wants to verify a NEW star landed, compare `stars` from `kordis info
60
+ <full_slug> --json` before and after.
46
61
 
47
62
  ### `kordis unstar <full_slug> [--json]`
48
63
  Remove your star. Idempotent — silent no-op when not previously starred.
@@ -43,6 +43,15 @@ Writes files into the current project.
43
43
  | `--target <path>` | install into a sub-directory (default: cwd) |
44
44
  | `--with-recommends` | also install recommended dependencies |
45
45
 
46
+ IMPORTANT: `pull` **fails fast** when the target tool can't be inferred from
47
+ the cwd (no `.claude/`, `.codex/`, `.cursor/`, `AGENTS.md`, `CLAUDE.md`,
48
+ etc.). Pass `--tool <name>` explicitly when running in a project that has
49
+ not been initialised for any specific tool yet. Don't rely on the old "drop
50
+ a canonical SKILL.md at cwd" fallback — Claude Code never picked it up.
51
+
52
+ Valid `--tool` values: `claude-code`, `codex`, `cursor`, `continue`,
53
+ `windsurf`, `antigravity`, `copilot`.
54
+
46
55
  ### `kordis info <full_slug> --json`
47
56
  Inspect metadata (description, tier, deps, license, review status, …) before
48
57
  reading or pulling. ALWAYS run this for `mcp-server` / `hook` types, where the
@@ -91,6 +100,13 @@ auto-resolve silently.
91
100
  `"following <full_slug>@<version>"`). RECOMMENDED: end your reply with that
92
101
  exact line. Skip only when it would clutter a casual non-technical reply.
93
102
 
103
+ ## Bundled assets caveat
104
+ A skill body may reference helper files (e.g. `references/<file>.md`,
105
+ `scripts/<file>.sh`). Today the registry stores only the canonical
106
+ SKILL.md text — bundled side-files are NOT shipped. If the body refers to
107
+ one and you need it, follow the package's `homepage` to the upstream
108
+ source instead of fabricating the asset.
109
+
94
110
  ## Examples
95
111
 
96
112
  <example>
package/dist/index.js CHANGED
@@ -1435,6 +1435,13 @@ function pushCommand() {
1435
1435
  `${c.bold(res.full_slug)} ${c.gray(`v${res.version}`)} \u2192 ${res.status === "published" ? c.green("published") : res.status === "pending" ? c.yellow("pending review") : c.red("rejected")}`
1436
1436
  );
1437
1437
  printHuman(` ${c.cyan(res.url)}`);
1438
+ if (res.status === "pending") {
1439
+ printHuman(
1440
+ c.yellow(
1441
+ ` ! AI review is still pending \u2014 re-check with \`kordis info ${res.full_slug} --json\` for the verdict.`
1442
+ )
1443
+ );
1444
+ }
1438
1445
  if (res.review.flags.length > 0) {
1439
1446
  printHuman(c.yellow(` ${res.review.flags.length} review flag(s):`));
1440
1447
  for (const f of res.review.flags) {
@@ -2255,6 +2262,11 @@ function pullCommand() {
2255
2262
  const userCwd = process.env["INIT_CWD"] ?? process.cwd();
2256
2263
  const installRoot = opts.target ?? userCwd;
2257
2264
  const detected = opts.tool ?? await detectTool(installRoot);
2265
+ if (!detected) {
2266
+ throw new Error(
2267
+ "Cannot detect target tool from the current directory.\n Pass --tool <name> explicitly. Valid: claude-code, codex, cursor,\n continue, windsurf, antigravity, copilot.\n Or run `kordis pull` inside a project that already has one of:\n .claude/, .codex/, .cursor/, AGENTS.md, CLAUDE.md, .cursorrules,\n .continue/, .windsurf/, .antigravity/, .github/copilot-instructions.md"
2268
+ );
2269
+ }
2258
2270
  const spin = spinner(`Pulling ${fullSlug}`);
2259
2271
  const detail = await bundle.api.getPackage(username, slug);
2260
2272
  await bundle.api.pull(username, slug);
@@ -2268,7 +2280,7 @@ function pullCommand() {
2268
2280
  }
2269
2281
  const written = [];
2270
2282
  const notes = [];
2271
- const format = detected ?? "canonical";
2283
+ const format = detected;
2272
2284
  try {
2273
2285
  const translator = getTranslator(parsed.type, format);
2274
2286
  const result = translator({
@@ -2768,6 +2780,7 @@ function handleError(err) {
2768
2780
  code: err.code,
2769
2781
  message: err.message,
2770
2782
  flags: err.flags,
2783
+ ...err.retryAfter !== void 0 ? { retry_after_seconds: err.retryAfter } : {},
2771
2784
  request_id: err.requestId
2772
2785
  }
2773
2786
  });
@@ -2776,6 +2789,9 @@ function handleError(err) {
2776
2789
  for (const f of err.flags) {
2777
2790
  printHuman(c.red(` - ${f.code}${f.message ? `: ${f.message}` : ""}`));
2778
2791
  }
2792
+ if (err.retryAfter !== void 0) {
2793
+ printHuman(c.yellow(` retry after: ${err.retryAfter}s`));
2794
+ }
2779
2795
  if (err.requestId) {
2780
2796
  printHuman(c.gray(` (request-id: ${err.requestId})`));
2781
2797
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rayul/kordis",
3
- "version": "0.1.8",
3
+ "version": "0.1.10",
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",