@rayul/kordis 0.6.4 → 0.6.6

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.
@@ -18,6 +18,13 @@ Publish a valid, AI-review-passing version. ALWAYS dry-run first.
18
18
  - `license` — SPDX (e.g. `MIT`, `Apache-2.0`, `CC-BY-4.0`).
19
19
  - Optional: `homepage`, `tags`, `type`.
20
20
 
21
+ **`type` auto-inference (0.6.4+):** The CLI infers `type: skill` when
22
+ you push a directory bundle, a `.skill` ZIP, OR a single file named
23
+ `SKILL.md` or `*.skill.md`. You don't need to write `type:` in the
24
+ frontmatter for any of these paths. Use `--type <t>` (or write the
25
+ field manually) only when pushing a different package type from a
26
+ single `.md` file that doesn't match the SKILL.md filename pattern.
27
+
21
28
  **`version` field handling:**
22
29
  - **First publish** — used as-is (else defaults to `0.1.0`).
23
30
  - **Update** — the registry computes the next version from
@@ -21,6 +21,7 @@ Keyword search; `--json` for parsing.
21
21
  | `--type <t>` | `skill`, `mcp-server`, `project-rules`, `custom-agent`, `hook` |
22
22
  | `--tool <s>` | filter by compatible tool (`claude-code`, `codex`, `cursor`, …) |
23
23
  | `--tier <t>` | filter by portability tier `A`/`B`/`C`/`D` |
24
+ | `--author <u>` | restrict to a single author. **When set, response includes exact `total`** (other filters return `total: null`). 0.6.4+. |
24
25
  | `--sort <m>` | `relevance` (default), `stars`, `downloads`, `recent`, `updated` |
25
26
  | `--trending` | list packages trending in `--window` (overrides `--sort`) |
26
27
  | `--rising` | list rising packages by 7d acceleration (overrides `--sort`) |
@@ -112,3 +113,11 @@ User: "show me the most-downloaded skills"
112
113
  - kordis search --type skill --sort downloads --json
113
114
  - list top results
114
115
  </example>
116
+
117
+ <example>
118
+ User: "how many packages has alice published?" / "alice가 publish한거 다 보여줘"
119
+ - kordis search --author alice --json
120
+ - the response carries an exact `total` field (other filters report
121
+ `total: null`); render "Showing N of M matches"
122
+ - do NOT post-process with jq for author filtering — use the flag
123
+ </example>
package/dist/index.js CHANGED
@@ -1204,6 +1204,7 @@ import { join as join2 } from "path";
1204
1204
  var SERVICE = "kordis";
1205
1205
  var plaintextWarningEmitted = false;
1206
1206
  async function loadKeytar() {
1207
+ if (process.env["KORDIS_NO_KEYCHAIN"] === "1") return null;
1207
1208
  try {
1208
1209
  const mod = await import("keytar");
1209
1210
  return mod.default ?? mod;
@@ -1583,29 +1584,53 @@ async function useClient() {
1583
1584
  baseUrl: cfg.apiUrl,
1584
1585
  userAgent: `kordis-cli/${VERSION} node/${process.version}`
1585
1586
  });
1587
+ const debug = process.env["KORDIS_DEBUG"] === "1";
1588
+ let pollResult = null;
1586
1589
  try {
1587
- const tokens = await bootstrapApi.pollDeviceFlow(pending.device_code);
1588
- const meClient = new KordisClient({
1589
- baseUrl: cfg.apiUrl,
1590
- userAgent: `kordis-cli/${VERSION} node/${process.version}`,
1591
- getAccessToken: () => tokens.access_token
1592
- });
1593
- const me = await meClient.me();
1594
- username = me.username;
1595
- currentTokens = {
1596
- access_token: tokens.access_token,
1597
- refresh_token: tokens.refresh_token,
1598
- session_id: tokens.session_id,
1599
- expires_at_epoch: Math.floor(Date.now() / 1e3) + tokens.expires_in
1600
- };
1601
- await keychain.save(username, currentTokens);
1602
- cfg = { ...cfg, username, sessionId: tokens.session_id };
1603
- await saveCliConfig(cfg);
1604
- await clearPending();
1590
+ pollResult = await bootstrapApi.pollDeviceFlow(pending.device_code);
1605
1591
  } catch (err) {
1606
1592
  const code = err.code;
1607
- if (code && code !== "authorization_pending") {
1593
+ if (code === "authorization_pending") {
1594
+ if (debug) process.stderr.write("[kordis] auto-finalize: authorization_pending (keeping pending)\n");
1595
+ } else {
1608
1596
  await clearPending();
1597
+ if (debug) {
1598
+ const msg = err instanceof Error ? err.message : String(err);
1599
+ process.stderr.write(`[kordis] auto-finalize: poll failed (code=${code ?? "none"}): ${msg}
1600
+ `);
1601
+ }
1602
+ }
1603
+ }
1604
+ if (pollResult) {
1605
+ try {
1606
+ const meClient = new KordisClient({
1607
+ baseUrl: cfg.apiUrl,
1608
+ userAgent: `kordis-cli/${VERSION} node/${process.version}`,
1609
+ getAccessToken: () => pollResult.access_token
1610
+ });
1611
+ const me = await meClient.me();
1612
+ username = me.username;
1613
+ currentTokens = {
1614
+ access_token: pollResult.access_token,
1615
+ refresh_token: pollResult.refresh_token,
1616
+ session_id: pollResult.session_id,
1617
+ expires_at_epoch: Math.floor(Date.now() / 1e3) + pollResult.expires_in
1618
+ };
1619
+ await keychain.save(username, currentTokens);
1620
+ cfg = { ...cfg, username, sessionId: pollResult.session_id };
1621
+ await saveCliConfig(cfg);
1622
+ await clearPending();
1623
+ if (debug) process.stderr.write(`[kordis] auto-finalize: persisted tokens for ${username}
1624
+ `);
1625
+ } catch (err) {
1626
+ await clearPending();
1627
+ currentTokens = null;
1628
+ username = null;
1629
+ const msg = err instanceof Error ? err.message : String(err);
1630
+ process.stderr.write(
1631
+ `[kordis] auto-finalize: server issued tokens but local persistence failed (${msg}). Run \`kordis login --emit-only\` again to retry.
1632
+ `
1633
+ );
1609
1634
  }
1610
1635
  }
1611
1636
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rayul/kordis",
3
- "version": "0.6.4",
3
+ "version": "0.6.6",
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",