Skip to content

Commit 61a2b63

Browse files
committed
refactor(skill): rename clerk-cli skill to clerk
Rename the bundled skill from `clerk-cli` to `clerk` everywhere the name appears as a skill identifier: directory path, frontmatter `name:`, user- facing copy, and the JS/TS identifiers that track it (import bindings, `BUNDLED_CLERK_SKILL`, `withStagedClerkSkill`, `installClerkSkillCore`). Leaves CLI-level identifiers untouched since changing them would orphan user state on upgrade: `KEYCHAIN_SERVICE = "clerk-cli"` (macOS keychain), `envPaths("clerk-cli", ...)` (OS config/cache paths), and the `clerk-cli-mock-auth` test-fixture package name.
1 parent ba1c026 commit 61a2b63

File tree

13 files changed

+71
-78
lines changed

13 files changed

+71
-78
lines changed

.changeset/clerk-cli-skill.md

Lines changed: 0 additions & 5 deletions
This file was deleted.

.changeset/clerk-skill.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"clerk": minor
3+
---
4+
5+
Add `clerk skill install` to install the bundled `clerk` Claude Code skill into your project. The skill ships with the CLI and is pinned to the CLI's version, and `clerk init` now offers to install it alongside the framework-pattern skills.

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ Commands:
5555
(no args) Interactive request builder (TTY only)
5656
doctor [options] Check your project's Clerk integration health
5757
skill Manage the bundled Clerk CLI agent skill
58-
install [options] Install the bundled clerk-cli agent skill
58+
install [options] Install the bundled clerk agent skill
5959
switch-env [environment] Switch the active Clerk CLI environment
6060
completion [shell] Generate shell autocompletion script
6161
update [options] Update the Clerk CLI to the latest version

packages/cli-core/src/cli-program.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -487,7 +487,7 @@ Tutorial — enable completions for your shell:
487487
.command("skill")
488488
.description("Manage the bundled Clerk CLI agent skill")
489489
.setExamples([
490-
{ command: "clerk skill install", description: "Install the clerk-cli agent skill" },
490+
{ command: "clerk skill install", description: "Install the clerk agent skill" },
491491
{
492492
command: "clerk skill install -y",
493493
description: "Install non-interactively (auto-detect agents, global scope)",
@@ -496,7 +496,7 @@ Tutorial — enable completions for your shell:
496496

497497
skill
498498
.command("install")
499-
.description("Install the bundled clerk-cli agent skill")
499+
.description("Install the bundled clerk agent skill")
500500
.option("-y, --yes", "Skip prompts and run the `skills` CLI unattended")
501501
.addOption(
502502
createOption("--pm <manager>", "Package manager hint for runner detection").choices(

packages/cli-core/src/commands/init/README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -185,17 +185,17 @@ After scaffolding (and after env keys are pulled or keyless instructions are pri
185185

186186
- **Human mode**: prompts `Install agent skills? (...)` defaulting to yes. Pass `--no-skills` to suppress the prompt entirely, or `-y/--yes` to accept it without confirmation. When more than one runner is available, a second prompt picks which one to use (the project's package manager wins by default).
187187
- **Agent mode**: skills are installed non-interactively with `-y -g` flags (no prompt shown). Pass `--no-skills` to skip entirely.
188-
- **`--prompt`**: exits before the skills step runs. Agent users should run `skills add clerk/skills` via their preferred runner manually; the bundled `clerk-cli` skill is only installable via `clerk init` itself, since its source lives inside the CLI binary.
188+
- **`--prompt`**: exits before the skills step runs. Agent users should run `skills add clerk/skills` via their preferred runner manually; the bundled `clerk` skill is only installable via `clerk init` itself, since its source lives inside the CLI binary.
189189

190190
Two install commands run, sharing one runner:
191191

192-
### 1. The bundled `clerk-cli` skill
192+
### 1. The bundled `clerk` skill
193193

194-
The `clerk-cli` skill ships **inside the CLI binary**. Its markdown files at [`<repo-root>/skills/clerk-cli/`](../../../../../skills/clerk-cli/) are pulled into [`skills.ts`](./skills.ts) as [text imports](https://bun.com/docs/bundler/loaders#text) (`import md from "./SKILL.md" with { type: "text" }`) and embedded by `bun build --compile`, so the skill content always matches the binary running it. No network, no tag, no version fallback.
194+
The `clerk` skill ships **inside the CLI binary**. Its markdown files at [`<repo-root>/skills/clerk/`](../../../../../skills/clerk/) are pulled into [`skills.ts`](./skills.ts) as [text imports](https://bun.com/docs/bundler/loaders#text) (`import md from "./SKILL.md" with { type: "text" }`) and embedded by `bun build --compile`, so the skill content always matches the binary running it. No network, no tag, no version fallback.
195195

196196
At install time, [`skills.ts`](./skills.ts) stages the bundled content into a fresh temp directory (`mkdtemp`) and invokes `<runner> skills add <tmpdir> --copy`. The `--copy` flag is required: the default symlink mode would point each agent's skill dir at the temp dir, which we delete immediately after the install completes.
197197

198-
The `skills` CLI writes the installed files into each agent's skill directory (`.claude/skills/clerk-cli/`, `.cursor/skills/clerk-cli/`, etc.) and records the entry in the project's `skills-lock.json` with `sourceType: "local"`, which correctly excludes it from `skills update` (the skill can only change when the CLI itself is upgraded).
198+
The `skills` CLI writes the installed files into each agent's skill directory (`.claude/skills/clerk/`, `.cursor/skills/clerk/`, etc.) and records the entry in the project's `skills-lock.json` with `sourceType: "local"`, which correctly excludes it from `skills update` (the skill can only change when the CLI itself is upgraded).
199199

200200
### 2. The upstream framework-pattern skills
201201

@@ -218,7 +218,7 @@ These skills version independently of the CLI, so no pin is applied.
218218

219219
### Failure handling
220220

221-
The two install commands fail independently: a problem with the bundled `clerk-cli` skill install (e.g. the `skills` CLI can't be fetched by the runner) does not block the upstream skills install, and vice versa. Each failure prints its own yellow warning with a manual install command (where applicable — the bundled `clerk-cli` skill has no standalone manual command, since its source lives in the binary). Init continues and exits successfully either way.
221+
The two install commands fail independently: a problem with the bundled `clerk` skill install (e.g. the `skills` CLI can't be fetched by the runner) does not block the upstream skills install, and vice versa. Each failure prints its own yellow warning with a manual install command (where applicable — the bundled `clerk` skill has no standalone manual command, since its source lives in the binary). Init continues and exits successfully either way.
222222

223223
Implementation lives in [`skills.ts`](./skills.ts). Note that the E2E fixture setup runs `clerk init --yes --no-skills` because the framework template skills reference auto-generated types (e.g. React Router's `./+types/root`) that don't exist outside a real app directory and would break the fixture's `tsc` step.
224224

packages/cli-core/src/commands/init/skills.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
*
44
* Two installer calls share one runner detection:
55
*
6-
* 1. The bundled `clerk-cli` skill (embedded in the binary via text
6+
* 1. The bundled `clerk` skill (embedded in the binary via text
77
* imports). Delegated to the `clerk skill install` core helpers in
88
* `commands/skill/install.ts`.
99
*
@@ -21,7 +21,7 @@ import { isHuman } from "../../mode.js";
2121
import { log } from "../../lib/log.js";
2222
import { confirm } from "../../lib/prompts.js";
2323
import type { ProjectContext } from "./frameworks/types.js";
24-
import { installClerkCliSkillCore, resolveSkillsRunner, runSkillsAdd } from "../skill/install.js";
24+
import { installClerkSkillCore, resolveSkillsRunner, runSkillsAdd } from "../skill/install.js";
2525

2626
/** Upstream skills installed regardless of framework. */
2727
const BASE_SKILLS = ["clerk", "clerk-setup"];
@@ -58,7 +58,7 @@ export async function installSkills(
5858
skipPrompt: boolean,
5959
): Promise<void> {
6060
const upstreamSkills = resolveUpstreamSkills(frameworkDep);
61-
const skillList = ["clerk-cli", ...upstreamSkills].join(", ");
61+
const skillList = ["clerk", ...upstreamSkills].join(", ");
6262

6363
if (isHuman() && !skipPrompt) {
6464
const install = await confirm({
@@ -74,10 +74,10 @@ export async function installSkills(
7474
const runner = await resolveSkillsRunner(packageManager, interactive);
7575
if (!runner) return;
7676

77-
// Install the bundled clerk-cli skill from a staged temp dir, then the
77+
// Install the bundled clerk skill from a staged temp dir, then the
7878
// upstream framework patterns. Each call soft-fails independently so a
7979
// problem with one source doesn't block the other.
80-
const cliSkillOk = await installClerkCliSkillCore(runner, cwd, interactive);
80+
const cliSkillOk = await installClerkSkillCore(runner, cwd, interactive);
8181

8282
const upstreamOk = await runSkillsAdd(
8383
runner,

packages/cli-core/src/commands/skill/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
# Skill Command
22

3-
Manages the bundled `clerk-cli` agent skill. The skill is embedded in the CLI binary at compile time via text imports from `skills/clerk-cli/`, so it always matches the version of the CLI in use.
3+
Manages the bundled `clerk` agent skill. The skill is embedded in the CLI binary at compile time via text imports from `skills/clerk/`, so it always matches the version of the CLI in use.
44

55
## Subcommands
66

77
### `clerk skill install`
88

9-
Installs the bundled `clerk-cli` skill for any locally detected AI agents (Claude Code, Cursor, etc.). The actual agent detection and scope selection is delegated to the external [`skills`](https://www.npmjs.com/package/skills) CLI, which is invoked via the preferred package runner on PATH (`bunx`, `pnpm dlx`, `yarn dlx`, or `npx`).
9+
Installs the bundled `clerk` skill for any locally detected AI agents (Claude Code, Cursor, etc.). The actual agent detection and scope selection is delegated to the external [`skills`](https://www.npmjs.com/package/skills) CLI, which is invoked via the preferred package runner on PATH (`bunx`, `pnpm dlx`, `yarn dlx`, or `npx`).
1010

1111
Interactive mode hands off entirely to the `skills` CLI picker. Non-interactive mode (`-y`, agent mode, or no TTY) passes `-y -g` so the skills CLI runs unattended against global scope with auto-detected agents.
1212

packages/cli-core/src/commands/skill/install.test.ts

Lines changed: 21 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,7 @@ import { test, expect, describe } from "bun:test";
22
import { existsSync } from "node:fs";
33
import { readFile, stat } from "node:fs/promises";
44
import { join } from "node:path";
5-
import {
6-
buildSkillsArgs,
7-
renderSkillVersionPlaceholder,
8-
withStagedClerkCliSkill,
9-
} from "./install.ts";
5+
import { buildSkillsArgs, renderSkillVersionPlaceholder, withStagedClerkSkill } from "./install.ts";
106

117
describe("buildSkillsArgs", () => {
128
const skills = ["clerk", "clerk-setup", "clerk-nextjs-patterns"];
@@ -43,45 +39,42 @@ describe("buildSkillsArgs", () => {
4339
expect(buildSkillsArgs(upstream, skills, false, false)).not.toContain("--agent");
4440
});
4541

46-
test("empty skillNames omits --skill flags (used for the clerk-cli source)", () => {
47-
const stageDir = "/tmp/clerk-cli-skill-abc";
42+
test("empty skillNames omits --skill flags (used for the clerk source)", () => {
43+
const stageDir = "/tmp/clerk-skill-abc";
4844
const args = buildSkillsArgs(stageDir, [], true, true);
4945
expect(args).toEqual(["skills", "add", stageDir, "--copy"]);
5046
expect(args).not.toContain("--skill");
5147
});
5248

53-
test("copy=true appends --copy flag (required for the staged clerk-cli dir)", () => {
54-
const args = buildSkillsArgs("/tmp/clerk-cli-skill-xyz", [], false, true);
49+
test("copy=true appends --copy flag (required for the staged clerk dir)", () => {
50+
const args = buildSkillsArgs("/tmp/clerk-skill-xyz", [], false, true);
5551
expect(args).toContain("--copy");
5652
// --copy should trail -y / -g, not replace them.
5753
expect(args).toContain("-y");
5854
expect(args).toContain("-g");
5955
});
6056
});
6157

62-
describe("withStagedClerkCliSkill", () => {
58+
describe("withStagedClerkSkill", () => {
6359
test("stages all bundled files into a fresh temp dir and cleans up after", async () => {
6460
let observed: { dir: string; files: Record<string, string> } | null = null;
6561

66-
await withStagedClerkCliSkill(undefined, async (dir) => {
62+
await withStagedClerkSkill(undefined, async (dir) => {
6763
const files = {
68-
"clerk-cli/SKILL.md": await readFile(join(dir, "clerk-cli/SKILL.md"), "utf-8"),
69-
"clerk-cli/references/auth.md": await readFile(
70-
join(dir, "clerk-cli/references/auth.md"),
64+
"clerk/SKILL.md": await readFile(join(dir, "clerk/SKILL.md"), "utf-8"),
65+
"clerk/references/auth.md": await readFile(join(dir, "clerk/references/auth.md"), "utf-8"),
66+
"clerk/references/recipes.md": await readFile(
67+
join(dir, "clerk/references/recipes.md"),
7168
"utf-8",
7269
),
73-
"clerk-cli/references/recipes.md": await readFile(
74-
join(dir, "clerk-cli/references/recipes.md"),
75-
"utf-8",
76-
),
77-
"clerk-cli/references/agent-mode.md": await readFile(
78-
join(dir, "clerk-cli/references/agent-mode.md"),
70+
"clerk/references/agent-mode.md": await readFile(
71+
join(dir, "clerk/references/agent-mode.md"),
7972
"utf-8",
8073
),
8174
};
8275
observed = { dir, files };
8376

84-
const entry = await stat(join(dir, "clerk-cli"));
77+
const entry = await stat(join(dir, "clerk"));
8578
expect(entry.isDirectory()).toBe(true);
8679
});
8780

@@ -95,7 +88,7 @@ describe("withStagedClerkCliSkill", () => {
9588
}
9689

9790
// SKILL.md should at least contain the YAML frontmatter marker.
98-
expect(files["clerk-cli/SKILL.md"]).toContain("---");
91+
expect(files["clerk/SKILL.md"]).toContain("---");
9992

10093
// Temp dir is removed once the callback returns.
10194
expect(existsSync(dir)).toBe(false);
@@ -105,7 +98,7 @@ describe("withStagedClerkCliSkill", () => {
10598
let capturedDir: string | null = null;
10699

107100
await expect(
108-
withStagedClerkCliSkill(undefined, async (dir) => {
101+
withStagedClerkSkill(undefined, async (dir) => {
109102
capturedDir = dir;
110103
throw new Error("boom");
111104
}),
@@ -116,17 +109,17 @@ describe("withStagedClerkCliSkill", () => {
116109
});
117110
});
118111

119-
describe("withStagedClerkCliSkill version rendering", () => {
112+
describe("withStagedClerkSkill version rendering", () => {
120113
test("substitutes CLI_VERSION into the staged SKILL.md", async () => {
121-
await withStagedClerkCliSkill("4.5.6", async (stageDir) => {
122-
const skill = await readFile(join(stageDir, "clerk-cli/SKILL.md"), "utf8");
114+
await withStagedClerkSkill("4.5.6", async (stageDir) => {
115+
const skill = await readFile(join(stageDir, "clerk/SKILL.md"), "utf8");
123116
expect(skill).not.toContain("{{CLI_VERSION}}");
124117
});
125118
});
126119

127120
test("passes undefined through as `latest`", async () => {
128-
await withStagedClerkCliSkill(undefined, async (stageDir) => {
129-
const skill = await readFile(join(stageDir, "clerk-cli/SKILL.md"), "utf8");
121+
await withStagedClerkSkill(undefined, async (stageDir) => {
122+
const skill = await readFile(join(stageDir, "clerk/SKILL.md"), "utf8");
130123
expect(skill).not.toContain("{{CLI_VERSION}}");
131124
});
132125
});

0 commit comments

Comments
 (0)