Skip to content

feat: Clerk CLI Skill - #126

Merged
wyattjoh merged 19 commits into
mainfrom
feat/clerk-cli-skill-pinned
Apr 20, 2026
Merged

feat: Clerk CLI Skill#126
wyattjoh merged 19 commits into
mainfrom
feat/clerk-cli-skill-pinned

Conversation

@wyattjoh

@wyattjohwyattjoh commented Apr 7, 2026

Copy link
Copy Markdown
Contributor

Summary

Bundles the clerk skill into the CLI binary, pins it to the version of the binary that installed it, and teaches the skill how to invoke clerk using whatever runner the project prefers.

How it's bundled

  • Markdown files at <repo-root>/skills/clerk/ are pulled into skills.ts as text imports (import md from "./SKILL.md" with { type: "text" }). These resolve live during bun run dev and get embedded by bun build --compile, so the skill content always matches the binary running it.
  • At install time, the staged bundle is handed to <runner> skills add <tmpdir> --copy. --copy is required: the default symlink mode would point each agent's skill dir at the temp dir we delete right after the install.
  • skills-lock.json records the install with sourceType: "local", correctly excluding it from skills update. The skill can only change when the CLI is upgraded.

How it pins

  • Every asset is piped through a new renderSkillVersionPlaceholder(content, version) helper that substitutes {{CLI_VERSION}} at staging time. Release builds pin to the shipped version; dev builds (0.0.0-dev) resolve to latest.
  • DEV_CLI_VERSION and resolveCliVersion() live in a new lib/version.ts so the three sites that care about the dev sentinel (the --version fallback, the skill templater, and scripts/build.ts) share one source of truth and can't drift.

How the skill invokes clerk

A new "Invoking the CLI" section in SKILL.md teaches Claude to prefer a globally installed clerk binary first, and fall back to a pinned bunx / npx -y / pnpm dlx / yarn dlx in lockfile-preferred order. Mirrors the CLI's own preferredRunner logic.

Skill correctness

  • Removes a wrong claim that clerk init --prompt prints a framework-specific integration guide. It prints a short agent handoff telling the agent to run clerk init -y.
  • Resyncs the skill against the current CLI surface: adds init, apps create, open, completion, and skill install to the Core commands table; adds --destructive to config patch/put; strengthens the Prerequisites section so clerk doctor --json is the mandatory session-start check; documents agent-mode behavior for apps create and clerk open.
  • Adds --name (with --starter) to the init row and --secret-key to the api row in the Core commands table, and corrects the clerk api ls --platform apps example (dropped an erroneous --).
  • Repositions clerk <command> --help as the source of truth for flags so the skill stays a hint rather than a spec, reducing drift surface.
  • Ports useful additions from feat(clerk-cli): add Clerk CLI skill skills#29 (verified against CLI source): documents the clerk auth login/logout aliases (signup/signin/sign-in, signout/sign-out) and the top-level clerk login/clerk logout shortcuts; notes that config commands authenticate via the Platform API and ignore --secret-key; extends the --destructive explanation to config patch (same semantics as config put); adds a table mapping each failing clerk doctor check to the manual remediation command (auth login / link / env pull) so agents can remediate without --fix (which is disabled in agent mode).

Skill rename

The bundled skill is named clerk (directory: skills/clerk/, frontmatter name: clerk). CLI-level identifiers that ship to user state (macOS KEYCHAIN_SERVICE, envPaths config/cache dir) keep the clerk-cli name to avoid orphaning existing installs on upgrade.

Installer continuity

  • Upstream clerk/skills continues to install via default symlink mode; the two installer calls share runner detection and fail independently.
  • buildSkillsArgs gains a copy parameter and threads it through runSkillsAdd so only the clerk skill install gets --copy.

Stacked on #125.

Test plan

  • bun run test passes (unit tests cover buildSkillsArgs--copy, renderSkillVersionPlaceholder edge cases, and withStagedClerkSkill staging + cleanup + version rendering)
  • Manual: run clerk init in a sandbox; confirm clerk and framework-pattern installs both succeed; check skills-lock.json records clerk with sourceType: "local"
  • Manual: confirm .claude/skills/clerk/ contains real files (not a broken symlink) after init
  • Manual: confirm the installed SKILL.md no longer contains the literal {{CLI_VERSION}} after install

@wyattjoh

wyattjoh commented Apr 7, 2026

Copy link
Copy Markdown
ContributorAuthor

@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch from 40b1139 to 2b430c5CompareApril 7, 2026 19:40
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch from 26405f7 to 1e94859CompareApril 7, 2026 19:40
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch from 2b430c5 to bd75724CompareApril 7, 2026 20:23
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch from 1e94859 to 670617fCompareApril 7, 2026 20:23
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch from bd75724 to 510829cCompareApril 7, 2026 21:58
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch 2 times, most recently from 10da1db to a4185bbCompareApril 8, 2026 21:39
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch 2 times, most recently from dae4ecc to 75f79d4CompareApril 9, 2026 20:23
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch 2 times, most recently from a45b262 to c95a429CompareApril 9, 2026 22:54
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch from 75f79d4 to 2bc5f72CompareApril 9, 2026 22:54
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch from c95a429 to 79d474fCompareApril 11, 2026 06:48
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch from 2bc5f72 to c52bc3fCompareApril 11, 2026 06:48
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch from 79d474f to 08653a1CompareApril 11, 2026 06:54
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch from c52bc3f to 27b5058CompareApril 11, 2026 06:54
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch from 08653a1 to a8903e7CompareApril 13, 2026 20:01
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch 2 times, most recently from f0d314f to 8e087a7CompareApril 13, 2026 22:49
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch from a8903e7 to 190c5d5CompareApril 13, 2026 22:49
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch from 8e087a7 to 13e75abCompareApril 13, 2026 23:20
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch from 190c5d5 to 09c9f9bCompareApril 13, 2026 23:20
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch from 13e75ab to 7154722CompareApril 14, 2026 18:50
@wyattjohwyattjoh changed the title feat(init): version-pinned clerk-cli skill installerfeat(init): bundle clerk-cli skill into the binaryApr 14, 2026
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch from 09c9f9b to 59ca3dbCompareApril 14, 2026 18:56
Comment threadpackages/cli-core/src/commands/init/skills.ts
Comment threadpackages/cli-core/src/lib/version.ts
Comment threadpackages/cli-core/src/commands/skill/install.ts Outdated
Comment threadpackages/cli-core/src/commands/skill/install.test.ts
wyattjohand others added 19 commits April 20, 2026 09:00
Pulls the clerk-cli skill markdown files at <repo-root>/skills/clerk-cli/
into skills.ts as text imports (`import md from "./SKILL.md" with { type:
"text" }`), which resolve live during `bun run dev` and get embedded by
`bun build --compile`. The skill content therefore always matches the
binary running it, with no network lookup, no tag publishing race, and
no CLI_VERSION URL fallback.
At install time, `installSkills` stages the bundled content into a fresh
`mkdtemp` directory and invokes `<runner> skills add <tmpdir> --copy`.
The --copy flag is required: the `skills` CLI's default symlink mode
would point each agent's skill dir at the temp dir, which we delete
immediately after the install completes. Copy mode produces real files
in `.claude/skills/clerk-cli/` etc. and records the install 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).
The upstream `clerk/skills` install continues to use the default symlink
mode against the remote source. The two installer calls share one
runner detection and fail independently.
Installs the bundled clerk-cli skill standalone so projects set up before
the skill was bundled, or CLIs upgraded since, can pull it in without
re-running init. `init` now delegates the clerk-cli portion to shared
core in commands/skill/install.ts, keeping a single runner detection
across clerk-cli and upstream framework skills.
Also extracts PACKAGE_MANAGERS as the canonical tuple plus derived type
in lib/package-manager.ts, reused by both `init --pm` and
`skill install --pm` choices. PM_PRIORITY in bootstrap keeps its
semantic name via `satisfies readonly PackageManager[]` plus a
compile-time exhaustiveness guard.
Fix the nano-staged oxlint hook to pass `-c .oxlintrc.json` explicitly
so override files (e.g. `unicorn/no-process-exit` off in cli-program.ts)
apply when linting specific paths; bare `oxlint <file>` does not
auto-discover the config.
Hoists the dev-version sentinel to a shared lib/version module so
cli-program.ts and install.ts stay in lockstep. Adds resolveCliVersion()
which maps both undefined and the 0.0.0-dev sentinel to undefined, letting
downstream callers treat unversioned binaries uniformly.
Threads the resolved version through withStagedClerkCliSkill so every
bundled asset has {{CLI_VERSION}} substituted at install time. The install
caller uses resolveCliVersion() instead of an inline typeof guard.
Import DEV_CLI_VERSION from packages/cli-core/src/lib/version.ts in
scripts/build.ts so the build script's default version arg stays in
lockstep with the sentinel used by the skill installer. Also extend
scripts/tsconfig.json to include globals.d.ts so CLI_VERSION is in
scope when tsc follows the cross-package import.
Remove the PackageManager type re-export from bootstrap-registry and
update consumers (bootstrap.ts, context.ts, index.ts) to import the
type directly from lib/package-manager.ts.
Adds init, apps create, open, completion, and skill install to the
Core commands table; adds --destructive to config patch/put; clarifies
config put semantics. Strengthens the Prerequisites section to make
'clerk doctor --json' the mandatory session-start check, with a note
to rerun 'clerk skill install' after upgrading the CLI so the bundled
skill matches the new binary.
Adds agent-mode behavior rows for 'apps create' (requires explicit
--json) and 'clerk open' (emits a JSON descriptor instead of launching
a browser), plus matching entries in the structured-outputs table.
Calls out 'clerk <command> --help' as the source of truth for flags so
the skill stays a hint rather than a spec, reducing drift surface.
Hidden commands (deploy, switch-env) remain undocumented.
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.
The bundled clerk skill drifted from the CLI source in a few places.
This commit resyncs the command reference and agent-mode docs:
- `clerk init`: document `--app` (skips interactive picker)
- `clerk config patch`/`put`: document `--app` and `--instance`
- Add `clerk update` row to the core commands table
- `references/agent-mode.md`: document the structured JSON error
output (`{"error":{...}}` on stderr) that agent mode emits, split
error-format guidance into human vs agent columns
- SKILL.md: expand the `clerk doctor --json` shape to include
`detail` and `fix` alongside `remedy`
Correct documentation drift identified by skill audit:
- OpenAPI catalog cache TTL is 1 hour, not 24 hours (matches
CACHE_TTL_MS in packages/cli-core/src/lib/constants.ts).
- `apps create` auto-emits JSON in agent mode via the shared
printJson() helper, same as `apps list`; update agent-mode matrix
and SKILL.md bullet so agents don't unnecessarily add --json.
Pull the accurate, CLI-verified additions from the external clerk-cli skill
draft into the bundled clerk skill:
- Document auth aliases: signup/signin/sign-in, signout/sign-out, and the
top-level clerk login / clerk logout shortcuts.
- Explain --destructive on config patch (same semantics as on config put).
- Note that config commands authenticate via the Platform API and do not
accept --secret-key.
- Add a mapping from each failing clerk doctor check to the manual
remediation command (auth login / link / env pull), since doctor --fix
is disabled in agent mode.
PR #29 items skipped because they drift from the current CLI source:
the {checks, overall} doctor JSON wrapper (actual output is a flat array)
and doctor --fix working in agent mode (source gates it on isHuman()).
Co-authored-by: Rafael Thayto <rafa.thayto@gmail.com>
Replace hardcoded ~/.clerk/config.json and ~/.clerk/cache/ paths with
platform-agnostic guidance since constants.ts uses envPaths (XDG). Add
CLERK_CONFIG_DIR to the environment variables table.
- Remove "clerk" from BASE_SKILLS so the upstream clerk/skills install
no longer overwrites the bundled pinned skill
- Import DEV_CLI_VERSION in update-check.ts to eliminate duplicate sentinel
- Move detectPackageManager to lib/package-manager; re-export from context
- Expand version substitution tests to cover all 4 bundled skill files
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch from a1a52fd to 6d0ef8aCompareApril 20, 2026 15:00
@wyattjoh
wyattjoh merged commit 8c02278 into mainApr 20, 2026
10 checks passed
@wyattjoh
wyattjoh deleted the feat/clerk-cli-skill-pinned branch April 20, 2026 17:54
@github-actionsgithub-actionsBot mentioned this pull request Apr 20, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@wyattjoh@rafa-thayto
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
feat: Clerk CLI Skill by wyattjoh · Pull Request #126 · clerk/cli · GitHub
Skip to content

feat: Clerk CLI Skill - #126

Merged
wyattjoh merged 19 commits into
mainfrom
feat/clerk-cli-skill-pinned
Apr 20, 2026
Merged

feat: Clerk CLI Skill#126
wyattjoh merged 19 commits into
mainfrom
feat/clerk-cli-skill-pinned

Conversation

@wyattjoh

@wyattjohwyattjoh commented Apr 7, 2026

Copy link
Copy Markdown
Contributor

Summary

Bundles the clerk skill into the CLI binary, pins it to the version of the binary that installed it, and teaches the skill how to invoke clerk using whatever runner the project prefers.

How it's bundled

  • Markdown files at <repo-root>/skills/clerk/ are pulled into skills.ts as text imports (import md from "./SKILL.md" with { type: "text" }). These resolve live during bun run dev and get embedded by bun build --compile, so the skill content always matches the binary running it.
  • At install time, the staged bundle is handed to <runner> skills add <tmpdir> --copy. --copy is required: the default symlink mode would point each agent's skill dir at the temp dir we delete right after the install.
  • skills-lock.json records the install with sourceType: "local", correctly excluding it from skills update. The skill can only change when the CLI is upgraded.

How it pins

  • Every asset is piped through a new renderSkillVersionPlaceholder(content, version) helper that substitutes {{CLI_VERSION}} at staging time. Release builds pin to the shipped version; dev builds (0.0.0-dev) resolve to latest.
  • DEV_CLI_VERSION and resolveCliVersion() live in a new lib/version.ts so the three sites that care about the dev sentinel (the --version fallback, the skill templater, and scripts/build.ts) share one source of truth and can't drift.

How the skill invokes clerk

A new "Invoking the CLI" section in SKILL.md teaches Claude to prefer a globally installed clerk binary first, and fall back to a pinned bunx / npx -y / pnpm dlx / yarn dlx in lockfile-preferred order. Mirrors the CLI's own preferredRunner logic.

Skill correctness

  • Removes a wrong claim that clerk init --prompt prints a framework-specific integration guide. It prints a short agent handoff telling the agent to run clerk init -y.
  • Resyncs the skill against the current CLI surface: adds init, apps create, open, completion, and skill install to the Core commands table; adds --destructive to config patch/put; strengthens the Prerequisites section so clerk doctor --json is the mandatory session-start check; documents agent-mode behavior for apps create and clerk open.
  • Adds --name (with --starter) to the init row and --secret-key to the api row in the Core commands table, and corrects the clerk api ls --platform apps example (dropped an erroneous --).
  • Repositions clerk <command> --help as the source of truth for flags so the skill stays a hint rather than a spec, reducing drift surface.
  • Ports useful additions from feat(clerk-cli): add Clerk CLI skill skills#29 (verified against CLI source): documents the clerk auth login/logout aliases (signup/signin/sign-in, signout/sign-out) and the top-level clerk login/clerk logout shortcuts; notes that config commands authenticate via the Platform API and ignore --secret-key; extends the --destructive explanation to config patch (same semantics as config put); adds a table mapping each failing clerk doctor check to the manual remediation command (auth login / link / env pull) so agents can remediate without --fix (which is disabled in agent mode).

Skill rename

The bundled skill is named clerk (directory: skills/clerk/, frontmatter name: clerk). CLI-level identifiers that ship to user state (macOS KEYCHAIN_SERVICE, envPaths config/cache dir) keep the clerk-cli name to avoid orphaning existing installs on upgrade.

Installer continuity

  • Upstream clerk/skills continues to install via default symlink mode; the two installer calls share runner detection and fail independently.
  • buildSkillsArgs gains a copy parameter and threads it through runSkillsAdd so only the clerk skill install gets --copy.

Stacked on #125.

Test plan

  • bun run test passes (unit tests cover buildSkillsArgs--copy, renderSkillVersionPlaceholder edge cases, and withStagedClerkSkill staging + cleanup + version rendering)
  • Manual: run clerk init in a sandbox; confirm clerk and framework-pattern installs both succeed; check skills-lock.json records clerk with sourceType: "local"
  • Manual: confirm .claude/skills/clerk/ contains real files (not a broken symlink) after init
  • Manual: confirm the installed SKILL.md no longer contains the literal {{CLI_VERSION}} after install

@wyattjoh

wyattjoh commented Apr 7, 2026

Copy link
Copy Markdown
ContributorAuthor

@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch from 40b1139 to 2b430c5CompareApril 7, 2026 19:40
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch from 26405f7 to 1e94859CompareApril 7, 2026 19:40
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch from 2b430c5 to bd75724CompareApril 7, 2026 20:23
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch from 1e94859 to 670617fCompareApril 7, 2026 20:23
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch from bd75724 to 510829cCompareApril 7, 2026 21:58
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch 2 times, most recently from 10da1db to a4185bbCompareApril 8, 2026 21:39
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch 2 times, most recently from dae4ecc to 75f79d4CompareApril 9, 2026 20:23
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch 2 times, most recently from a45b262 to c95a429CompareApril 9, 2026 22:54
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch from 75f79d4 to 2bc5f72CompareApril 9, 2026 22:54
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch from c95a429 to 79d474fCompareApril 11, 2026 06:48
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch from 2bc5f72 to c52bc3fCompareApril 11, 2026 06:48
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch from 79d474f to 08653a1CompareApril 11, 2026 06:54
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch from c52bc3f to 27b5058CompareApril 11, 2026 06:54
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch from 08653a1 to a8903e7CompareApril 13, 2026 20:01
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch 2 times, most recently from f0d314f to 8e087a7CompareApril 13, 2026 22:49
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch from a8903e7 to 190c5d5CompareApril 13, 2026 22:49
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch from 8e087a7 to 13e75abCompareApril 13, 2026 23:20
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch from 190c5d5 to 09c9f9bCompareApril 13, 2026 23:20
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch from 13e75ab to 7154722CompareApril 14, 2026 18:50
@wyattjohwyattjoh changed the title feat(init): version-pinned clerk-cli skill installerfeat(init): bundle clerk-cli skill into the binaryApr 14, 2026
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch from 09c9f9b to 59ca3dbCompareApril 14, 2026 18:56
Comment threadpackages/cli-core/src/commands/init/skills.ts
Comment threadpackages/cli-core/src/lib/version.ts
Comment threadpackages/cli-core/src/commands/skill/install.ts Outdated
Comment threadpackages/cli-core/src/commands/skill/install.test.ts
wyattjohand others added 19 commits April 20, 2026 09:00
Pulls the clerk-cli skill markdown files at <repo-root>/skills/clerk-cli/
into skills.ts as text imports (`import md from "./SKILL.md" with { type:
"text" }`), which resolve live during `bun run dev` and get embedded by
`bun build --compile`. The skill content therefore always matches the
binary running it, with no network lookup, no tag publishing race, and
no CLI_VERSION URL fallback.
At install time, `installSkills` stages the bundled content into a fresh
`mkdtemp` directory and invokes `<runner> skills add <tmpdir> --copy`.
The --copy flag is required: the `skills` CLI's default symlink mode
would point each agent's skill dir at the temp dir, which we delete
immediately after the install completes. Copy mode produces real files
in `.claude/skills/clerk-cli/` etc. and records the install 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).
The upstream `clerk/skills` install continues to use the default symlink
mode against the remote source. The two installer calls share one
runner detection and fail independently.
Installs the bundled clerk-cli skill standalone so projects set up before
the skill was bundled, or CLIs upgraded since, can pull it in without
re-running init. `init` now delegates the clerk-cli portion to shared
core in commands/skill/install.ts, keeping a single runner detection
across clerk-cli and upstream framework skills.
Also extracts PACKAGE_MANAGERS as the canonical tuple plus derived type
in lib/package-manager.ts, reused by both `init --pm` and
`skill install --pm` choices. PM_PRIORITY in bootstrap keeps its
semantic name via `satisfies readonly PackageManager[]` plus a
compile-time exhaustiveness guard.
Fix the nano-staged oxlint hook to pass `-c .oxlintrc.json` explicitly
so override files (e.g. `unicorn/no-process-exit` off in cli-program.ts)
apply when linting specific paths; bare `oxlint <file>` does not
auto-discover the config.
Hoists the dev-version sentinel to a shared lib/version module so
cli-program.ts and install.ts stay in lockstep. Adds resolveCliVersion()
which maps both undefined and the 0.0.0-dev sentinel to undefined, letting
downstream callers treat unversioned binaries uniformly.
Threads the resolved version through withStagedClerkCliSkill so every
bundled asset has {{CLI_VERSION}} substituted at install time. The install
caller uses resolveCliVersion() instead of an inline typeof guard.
Import DEV_CLI_VERSION from packages/cli-core/src/lib/version.ts in
scripts/build.ts so the build script's default version arg stays in
lockstep with the sentinel used by the skill installer. Also extend
scripts/tsconfig.json to include globals.d.ts so CLI_VERSION is in
scope when tsc follows the cross-package import.
Remove the PackageManager type re-export from bootstrap-registry and
update consumers (bootstrap.ts, context.ts, index.ts) to import the
type directly from lib/package-manager.ts.
Adds init, apps create, open, completion, and skill install to the
Core commands table; adds --destructive to config patch/put; clarifies
config put semantics. Strengthens the Prerequisites section to make
'clerk doctor --json' the mandatory session-start check, with a note
to rerun 'clerk skill install' after upgrading the CLI so the bundled
skill matches the new binary.
Adds agent-mode behavior rows for 'apps create' (requires explicit
--json) and 'clerk open' (emits a JSON descriptor instead of launching
a browser), plus matching entries in the structured-outputs table.
Calls out 'clerk <command> --help' as the source of truth for flags so
the skill stays a hint rather than a spec, reducing drift surface.
Hidden commands (deploy, switch-env) remain undocumented.
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.
The bundled clerk skill drifted from the CLI source in a few places.
This commit resyncs the command reference and agent-mode docs:
- `clerk init`: document `--app` (skips interactive picker)
- `clerk config patch`/`put`: document `--app` and `--instance`
- Add `clerk update` row to the core commands table
- `references/agent-mode.md`: document the structured JSON error
output (`{"error":{...}}` on stderr) that agent mode emits, split
error-format guidance into human vs agent columns
- SKILL.md: expand the `clerk doctor --json` shape to include
`detail` and `fix` alongside `remedy`
Correct documentation drift identified by skill audit:
- OpenAPI catalog cache TTL is 1 hour, not 24 hours (matches
CACHE_TTL_MS in packages/cli-core/src/lib/constants.ts).
- `apps create` auto-emits JSON in agent mode via the shared
printJson() helper, same as `apps list`; update agent-mode matrix
and SKILL.md bullet so agents don't unnecessarily add --json.
Pull the accurate, CLI-verified additions from the external clerk-cli skill
draft into the bundled clerk skill:
- Document auth aliases: signup/signin/sign-in, signout/sign-out, and the
top-level clerk login / clerk logout shortcuts.
- Explain --destructive on config patch (same semantics as on config put).
- Note that config commands authenticate via the Platform API and do not
accept --secret-key.
- Add a mapping from each failing clerk doctor check to the manual
remediation command (auth login / link / env pull), since doctor --fix
is disabled in agent mode.
PR #29 items skipped because they drift from the current CLI source:
the {checks, overall} doctor JSON wrapper (actual output is a flat array)
and doctor --fix working in agent mode (source gates it on isHuman()).
Co-authored-by: Rafael Thayto <rafa.thayto@gmail.com>
Replace hardcoded ~/.clerk/config.json and ~/.clerk/cache/ paths with
platform-agnostic guidance since constants.ts uses envPaths (XDG). Add
CLERK_CONFIG_DIR to the environment variables table.
- Remove "clerk" from BASE_SKILLS so the upstream clerk/skills install
no longer overwrites the bundled pinned skill
- Import DEV_CLI_VERSION in update-check.ts to eliminate duplicate sentinel
- Move detectPackageManager to lib/package-manager; re-export from context
- Expand version substitution tests to cover all 4 bundled skill files
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch from a1a52fd to 6d0ef8aCompareApril 20, 2026 15:00
@wyattjoh
wyattjoh merged commit 8c02278 into mainApr 20, 2026
10 checks passed
@wyattjoh
wyattjoh deleted the feat/clerk-cli-skill-pinned branch April 20, 2026 17:54
@github-actionsgithub-actionsBot mentioned this pull request Apr 20, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@wyattjoh@rafa-thayto
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' feat: Clerk CLI Skill by wyattjoh · Pull Request #126 · clerk/cli · GitHub
Skip to content

feat: Clerk CLI Skill - #126

Merged
wyattjoh merged 19 commits into
mainfrom
feat/clerk-cli-skill-pinned
Apr 20, 2026
Merged

feat: Clerk CLI Skill#126
wyattjoh merged 19 commits into
mainfrom
feat/clerk-cli-skill-pinned

Conversation

@wyattjoh

@wyattjohwyattjoh commented Apr 7, 2026

Copy link
Copy Markdown
Contributor

Summary

Bundles the clerk skill into the CLI binary, pins it to the version of the binary that installed it, and teaches the skill how to invoke clerk using whatever runner the project prefers.

How it's bundled

  • Markdown files at <repo-root>/skills/clerk/ are pulled into skills.ts as text imports (import md from "./SKILL.md" with { type: "text" }). These resolve live during bun run dev and get embedded by bun build --compile, so the skill content always matches the binary running it.
  • At install time, the staged bundle is handed to <runner> skills add <tmpdir> --copy. --copy is required: the default symlink mode would point each agent's skill dir at the temp dir we delete right after the install.
  • skills-lock.json records the install with sourceType: "local", correctly excluding it from skills update. The skill can only change when the CLI is upgraded.

How it pins

  • Every asset is piped through a new renderSkillVersionPlaceholder(content, version) helper that substitutes {{CLI_VERSION}} at staging time. Release builds pin to the shipped version; dev builds (0.0.0-dev) resolve to latest.
  • DEV_CLI_VERSION and resolveCliVersion() live in a new lib/version.ts so the three sites that care about the dev sentinel (the --version fallback, the skill templater, and scripts/build.ts) share one source of truth and can't drift.

How the skill invokes clerk

A new "Invoking the CLI" section in SKILL.md teaches Claude to prefer a globally installed clerk binary first, and fall back to a pinned bunx / npx -y / pnpm dlx / yarn dlx in lockfile-preferred order. Mirrors the CLI's own preferredRunner logic.

Skill correctness

  • Removes a wrong claim that clerk init --prompt prints a framework-specific integration guide. It prints a short agent handoff telling the agent to run clerk init -y.
  • Resyncs the skill against the current CLI surface: adds init, apps create, open, completion, and skill install to the Core commands table; adds --destructive to config patch/put; strengthens the Prerequisites section so clerk doctor --json is the mandatory session-start check; documents agent-mode behavior for apps create and clerk open.
  • Adds --name (with --starter) to the init row and --secret-key to the api row in the Core commands table, and corrects the clerk api ls --platform apps example (dropped an erroneous --).
  • Repositions clerk <command> --help as the source of truth for flags so the skill stays a hint rather than a spec, reducing drift surface.
  • Ports useful additions from feat(clerk-cli): add Clerk CLI skill skills#29 (verified against CLI source): documents the clerk auth login/logout aliases (signup/signin/sign-in, signout/sign-out) and the top-level clerk login/clerk logout shortcuts; notes that config commands authenticate via the Platform API and ignore --secret-key; extends the --destructive explanation to config patch (same semantics as config put); adds a table mapping each failing clerk doctor check to the manual remediation command (auth login / link / env pull) so agents can remediate without --fix (which is disabled in agent mode).

Skill rename

The bundled skill is named clerk (directory: skills/clerk/, frontmatter name: clerk). CLI-level identifiers that ship to user state (macOS KEYCHAIN_SERVICE, envPaths config/cache dir) keep the clerk-cli name to avoid orphaning existing installs on upgrade.

Installer continuity

  • Upstream clerk/skills continues to install via default symlink mode; the two installer calls share runner detection and fail independently.
  • buildSkillsArgs gains a copy parameter and threads it through runSkillsAdd so only the clerk skill install gets --copy.

Stacked on #125.

Test plan

  • bun run test passes (unit tests cover buildSkillsArgs--copy, renderSkillVersionPlaceholder edge cases, and withStagedClerkSkill staging + cleanup + version rendering)
  • Manual: run clerk init in a sandbox; confirm clerk and framework-pattern installs both succeed; check skills-lock.json records clerk with sourceType: "local"
  • Manual: confirm .claude/skills/clerk/ contains real files (not a broken symlink) after init
  • Manual: confirm the installed SKILL.md no longer contains the literal {{CLI_VERSION}} after install

@wyattjoh

wyattjoh commented Apr 7, 2026

Copy link
Copy Markdown
ContributorAuthor

@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch from 40b1139 to 2b430c5CompareApril 7, 2026 19:40
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch from 26405f7 to 1e94859CompareApril 7, 2026 19:40
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch from 2b430c5 to bd75724CompareApril 7, 2026 20:23
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch from 1e94859 to 670617fCompareApril 7, 2026 20:23
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch from bd75724 to 510829cCompareApril 7, 2026 21:58
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch 2 times, most recently from 10da1db to a4185bbCompareApril 8, 2026 21:39
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch 2 times, most recently from dae4ecc to 75f79d4CompareApril 9, 2026 20:23
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch 2 times, most recently from a45b262 to c95a429CompareApril 9, 2026 22:54
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch from 75f79d4 to 2bc5f72CompareApril 9, 2026 22:54
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch from c95a429 to 79d474fCompareApril 11, 2026 06:48
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch from 2bc5f72 to c52bc3fCompareApril 11, 2026 06:48
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch from 79d474f to 08653a1CompareApril 11, 2026 06:54
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch from c52bc3f to 27b5058CompareApril 11, 2026 06:54
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch from 08653a1 to a8903e7CompareApril 13, 2026 20:01
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch 2 times, most recently from f0d314f to 8e087a7CompareApril 13, 2026 22:49
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch from a8903e7 to 190c5d5CompareApril 13, 2026 22:49
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch from 8e087a7 to 13e75abCompareApril 13, 2026 23:20
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch from 190c5d5 to 09c9f9bCompareApril 13, 2026 23:20
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch from 13e75ab to 7154722CompareApril 14, 2026 18:50
@wyattjohwyattjoh changed the title feat(init): version-pinned clerk-cli skill installerfeat(init): bundle clerk-cli skill into the binaryApr 14, 2026
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch from 09c9f9b to 59ca3dbCompareApril 14, 2026 18:56
Comment threadpackages/cli-core/src/commands/init/skills.ts
Comment threadpackages/cli-core/src/lib/version.ts
Comment threadpackages/cli-core/src/commands/skill/install.ts Outdated
Comment threadpackages/cli-core/src/commands/skill/install.test.ts
wyattjohand others added 19 commits April 20, 2026 09:00
Pulls the clerk-cli skill markdown files at <repo-root>/skills/clerk-cli/
into skills.ts as text imports (`import md from "./SKILL.md" with { type:
"text" }`), which resolve live during `bun run dev` and get embedded by
`bun build --compile`. The skill content therefore always matches the
binary running it, with no network lookup, no tag publishing race, and
no CLI_VERSION URL fallback.
At install time, `installSkills` stages the bundled content into a fresh
`mkdtemp` directory and invokes `<runner> skills add <tmpdir> --copy`.
The --copy flag is required: the `skills` CLI's default symlink mode
would point each agent's skill dir at the temp dir, which we delete
immediately after the install completes. Copy mode produces real files
in `.claude/skills/clerk-cli/` etc. and records the install 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).
The upstream `clerk/skills` install continues to use the default symlink
mode against the remote source. The two installer calls share one
runner detection and fail independently.
Installs the bundled clerk-cli skill standalone so projects set up before
the skill was bundled, or CLIs upgraded since, can pull it in without
re-running init. `init` now delegates the clerk-cli portion to shared
core in commands/skill/install.ts, keeping a single runner detection
across clerk-cli and upstream framework skills.
Also extracts PACKAGE_MANAGERS as the canonical tuple plus derived type
in lib/package-manager.ts, reused by both `init --pm` and
`skill install --pm` choices. PM_PRIORITY in bootstrap keeps its
semantic name via `satisfies readonly PackageManager[]` plus a
compile-time exhaustiveness guard.
Fix the nano-staged oxlint hook to pass `-c .oxlintrc.json` explicitly
so override files (e.g. `unicorn/no-process-exit` off in cli-program.ts)
apply when linting specific paths; bare `oxlint <file>` does not
auto-discover the config.
Hoists the dev-version sentinel to a shared lib/version module so
cli-program.ts and install.ts stay in lockstep. Adds resolveCliVersion()
which maps both undefined and the 0.0.0-dev sentinel to undefined, letting
downstream callers treat unversioned binaries uniformly.
Threads the resolved version through withStagedClerkCliSkill so every
bundled asset has {{CLI_VERSION}} substituted at install time. The install
caller uses resolveCliVersion() instead of an inline typeof guard.
Import DEV_CLI_VERSION from packages/cli-core/src/lib/version.ts in
scripts/build.ts so the build script's default version arg stays in
lockstep with the sentinel used by the skill installer. Also extend
scripts/tsconfig.json to include globals.d.ts so CLI_VERSION is in
scope when tsc follows the cross-package import.
Remove the PackageManager type re-export from bootstrap-registry and
update consumers (bootstrap.ts, context.ts, index.ts) to import the
type directly from lib/package-manager.ts.
Adds init, apps create, open, completion, and skill install to the
Core commands table; adds --destructive to config patch/put; clarifies
config put semantics. Strengthens the Prerequisites section to make
'clerk doctor --json' the mandatory session-start check, with a note
to rerun 'clerk skill install' after upgrading the CLI so the bundled
skill matches the new binary.
Adds agent-mode behavior rows for 'apps create' (requires explicit
--json) and 'clerk open' (emits a JSON descriptor instead of launching
a browser), plus matching entries in the structured-outputs table.
Calls out 'clerk <command> --help' as the source of truth for flags so
the skill stays a hint rather than a spec, reducing drift surface.
Hidden commands (deploy, switch-env) remain undocumented.
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.
The bundled clerk skill drifted from the CLI source in a few places.
This commit resyncs the command reference and agent-mode docs:
- `clerk init`: document `--app` (skips interactive picker)
- `clerk config patch`/`put`: document `--app` and `--instance`
- Add `clerk update` row to the core commands table
- `references/agent-mode.md`: document the structured JSON error
output (`{"error":{...}}` on stderr) that agent mode emits, split
error-format guidance into human vs agent columns
- SKILL.md: expand the `clerk doctor --json` shape to include
`detail` and `fix` alongside `remedy`
Correct documentation drift identified by skill audit:
- OpenAPI catalog cache TTL is 1 hour, not 24 hours (matches
CACHE_TTL_MS in packages/cli-core/src/lib/constants.ts).
- `apps create` auto-emits JSON in agent mode via the shared
printJson() helper, same as `apps list`; update agent-mode matrix
and SKILL.md bullet so agents don't unnecessarily add --json.
Pull the accurate, CLI-verified additions from the external clerk-cli skill
draft into the bundled clerk skill:
- Document auth aliases: signup/signin/sign-in, signout/sign-out, and the
top-level clerk login / clerk logout shortcuts.
- Explain --destructive on config patch (same semantics as on config put).
- Note that config commands authenticate via the Platform API and do not
accept --secret-key.
- Add a mapping from each failing clerk doctor check to the manual
remediation command (auth login / link / env pull), since doctor --fix
is disabled in agent mode.
PR #29 items skipped because they drift from the current CLI source:
the {checks, overall} doctor JSON wrapper (actual output is a flat array)
and doctor --fix working in agent mode (source gates it on isHuman()).
Co-authored-by: Rafael Thayto <rafa.thayto@gmail.com>
Replace hardcoded ~/.clerk/config.json and ~/.clerk/cache/ paths with
platform-agnostic guidance since constants.ts uses envPaths (XDG). Add
CLERK_CONFIG_DIR to the environment variables table.
- Remove "clerk" from BASE_SKILLS so the upstream clerk/skills install
no longer overwrites the bundled pinned skill
- Import DEV_CLI_VERSION in update-check.ts to eliminate duplicate sentinel
- Move detectPackageManager to lib/package-manager; re-export from context
- Expand version substitution tests to cover all 4 bundled skill files
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch from a1a52fd to 6d0ef8aCompareApril 20, 2026 15:00
@wyattjoh
wyattjoh merged commit 8c02278 into mainApr 20, 2026
10 checks passed
@wyattjoh
wyattjoh deleted the feat/clerk-cli-skill-pinned branch April 20, 2026 17:54
@github-actionsgithub-actionsBot mentioned this pull request Apr 20, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@wyattjoh@rafa-thayto
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' feat: Clerk CLI Skill by wyattjoh · Pull Request #126 · clerk/cli · GitHub
Skip to content

feat: Clerk CLI Skill - #126

Merged
wyattjoh merged 19 commits into
mainfrom
feat/clerk-cli-skill-pinned
Apr 20, 2026
Merged

feat: Clerk CLI Skill#126
wyattjoh merged 19 commits into
mainfrom
feat/clerk-cli-skill-pinned

Conversation

@wyattjoh

@wyattjohwyattjoh commented Apr 7, 2026

Copy link
Copy Markdown
Contributor

Summary

Bundles the clerk skill into the CLI binary, pins it to the version of the binary that installed it, and teaches the skill how to invoke clerk using whatever runner the project prefers.

How it's bundled

  • Markdown files at <repo-root>/skills/clerk/ are pulled into skills.ts as text imports (import md from "./SKILL.md" with { type: "text" }). These resolve live during bun run dev and get embedded by bun build --compile, so the skill content always matches the binary running it.
  • At install time, the staged bundle is handed to <runner> skills add <tmpdir> --copy. --copy is required: the default symlink mode would point each agent's skill dir at the temp dir we delete right after the install.
  • skills-lock.json records the install with sourceType: "local", correctly excluding it from skills update. The skill can only change when the CLI is upgraded.

How it pins

  • Every asset is piped through a new renderSkillVersionPlaceholder(content, version) helper that substitutes {{CLI_VERSION}} at staging time. Release builds pin to the shipped version; dev builds (0.0.0-dev) resolve to latest.
  • DEV_CLI_VERSION and resolveCliVersion() live in a new lib/version.ts so the three sites that care about the dev sentinel (the --version fallback, the skill templater, and scripts/build.ts) share one source of truth and can't drift.

How the skill invokes clerk

A new "Invoking the CLI" section in SKILL.md teaches Claude to prefer a globally installed clerk binary first, and fall back to a pinned bunx / npx -y / pnpm dlx / yarn dlx in lockfile-preferred order. Mirrors the CLI's own preferredRunner logic.

Skill correctness

  • Removes a wrong claim that clerk init --prompt prints a framework-specific integration guide. It prints a short agent handoff telling the agent to run clerk init -y.
  • Resyncs the skill against the current CLI surface: adds init, apps create, open, completion, and skill install to the Core commands table; adds --destructive to config patch/put; strengthens the Prerequisites section so clerk doctor --json is the mandatory session-start check; documents agent-mode behavior for apps create and clerk open.
  • Adds --name (with --starter) to the init row and --secret-key to the api row in the Core commands table, and corrects the clerk api ls --platform apps example (dropped an erroneous --).
  • Repositions clerk <command> --help as the source of truth for flags so the skill stays a hint rather than a spec, reducing drift surface.
  • Ports useful additions from feat(clerk-cli): add Clerk CLI skill skills#29 (verified against CLI source): documents the clerk auth login/logout aliases (signup/signin/sign-in, signout/sign-out) and the top-level clerk login/clerk logout shortcuts; notes that config commands authenticate via the Platform API and ignore --secret-key; extends the --destructive explanation to config patch (same semantics as config put); adds a table mapping each failing clerk doctor check to the manual remediation command (auth login / link / env pull) so agents can remediate without --fix (which is disabled in agent mode).

Skill rename

The bundled skill is named clerk (directory: skills/clerk/, frontmatter name: clerk). CLI-level identifiers that ship to user state (macOS KEYCHAIN_SERVICE, envPaths config/cache dir) keep the clerk-cli name to avoid orphaning existing installs on upgrade.

Installer continuity

  • Upstream clerk/skills continues to install via default symlink mode; the two installer calls share runner detection and fail independently.
  • buildSkillsArgs gains a copy parameter and threads it through runSkillsAdd so only the clerk skill install gets --copy.

Stacked on #125.

Test plan

  • bun run test passes (unit tests cover buildSkillsArgs--copy, renderSkillVersionPlaceholder edge cases, and withStagedClerkSkill staging + cleanup + version rendering)
  • Manual: run clerk init in a sandbox; confirm clerk and framework-pattern installs both succeed; check skills-lock.json records clerk with sourceType: "local"
  • Manual: confirm .claude/skills/clerk/ contains real files (not a broken symlink) after init
  • Manual: confirm the installed SKILL.md no longer contains the literal {{CLI_VERSION}} after install

@wyattjoh

wyattjoh commented Apr 7, 2026

Copy link
Copy Markdown
ContributorAuthor

@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch from 40b1139 to 2b430c5CompareApril 7, 2026 19:40
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch from 26405f7 to 1e94859CompareApril 7, 2026 19:40
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch from 2b430c5 to bd75724CompareApril 7, 2026 20:23
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch from 1e94859 to 670617fCompareApril 7, 2026 20:23
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch from bd75724 to 510829cCompareApril 7, 2026 21:58
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch 2 times, most recently from 10da1db to a4185bbCompareApril 8, 2026 21:39
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch 2 times, most recently from dae4ecc to 75f79d4CompareApril 9, 2026 20:23
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch 2 times, most recently from a45b262 to c95a429CompareApril 9, 2026 22:54
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch from 75f79d4 to 2bc5f72CompareApril 9, 2026 22:54
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch from c95a429 to 79d474fCompareApril 11, 2026 06:48
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch from 2bc5f72 to c52bc3fCompareApril 11, 2026 06:48
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch from 79d474f to 08653a1CompareApril 11, 2026 06:54
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch from c52bc3f to 27b5058CompareApril 11, 2026 06:54
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch from 08653a1 to a8903e7CompareApril 13, 2026 20:01
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch 2 times, most recently from f0d314f to 8e087a7CompareApril 13, 2026 22:49
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch from a8903e7 to 190c5d5CompareApril 13, 2026 22:49
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch from 8e087a7 to 13e75abCompareApril 13, 2026 23:20
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch from 190c5d5 to 09c9f9bCompareApril 13, 2026 23:20
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch from 13e75ab to 7154722CompareApril 14, 2026 18:50
@wyattjohwyattjoh changed the title feat(init): version-pinned clerk-cli skill installerfeat(init): bundle clerk-cli skill into the binaryApr 14, 2026
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch from 09c9f9b to 59ca3dbCompareApril 14, 2026 18:56
Comment threadpackages/cli-core/src/commands/init/skills.ts
Comment threadpackages/cli-core/src/lib/version.ts
Comment threadpackages/cli-core/src/commands/skill/install.ts Outdated
Comment threadpackages/cli-core/src/commands/skill/install.test.ts
wyattjohand others added 19 commits April 20, 2026 09:00
Pulls the clerk-cli skill markdown files at <repo-root>/skills/clerk-cli/
into skills.ts as text imports (`import md from "./SKILL.md" with { type:
"text" }`), which resolve live during `bun run dev` and get embedded by
`bun build --compile`. The skill content therefore always matches the
binary running it, with no network lookup, no tag publishing race, and
no CLI_VERSION URL fallback.
At install time, `installSkills` stages the bundled content into a fresh
`mkdtemp` directory and invokes `<runner> skills add <tmpdir> --copy`.
The --copy flag is required: the `skills` CLI's default symlink mode
would point each agent's skill dir at the temp dir, which we delete
immediately after the install completes. Copy mode produces real files
in `.claude/skills/clerk-cli/` etc. and records the install 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).
The upstream `clerk/skills` install continues to use the default symlink
mode against the remote source. The two installer calls share one
runner detection and fail independently.
Installs the bundled clerk-cli skill standalone so projects set up before
the skill was bundled, or CLIs upgraded since, can pull it in without
re-running init. `init` now delegates the clerk-cli portion to shared
core in commands/skill/install.ts, keeping a single runner detection
across clerk-cli and upstream framework skills.
Also extracts PACKAGE_MANAGERS as the canonical tuple plus derived type
in lib/package-manager.ts, reused by both `init --pm` and
`skill install --pm` choices. PM_PRIORITY in bootstrap keeps its
semantic name via `satisfies readonly PackageManager[]` plus a
compile-time exhaustiveness guard.
Fix the nano-staged oxlint hook to pass `-c .oxlintrc.json` explicitly
so override files (e.g. `unicorn/no-process-exit` off in cli-program.ts)
apply when linting specific paths; bare `oxlint <file>` does not
auto-discover the config.
Hoists the dev-version sentinel to a shared lib/version module so
cli-program.ts and install.ts stay in lockstep. Adds resolveCliVersion()
which maps both undefined and the 0.0.0-dev sentinel to undefined, letting
downstream callers treat unversioned binaries uniformly.
Threads the resolved version through withStagedClerkCliSkill so every
bundled asset has {{CLI_VERSION}} substituted at install time. The install
caller uses resolveCliVersion() instead of an inline typeof guard.
Import DEV_CLI_VERSION from packages/cli-core/src/lib/version.ts in
scripts/build.ts so the build script's default version arg stays in
lockstep with the sentinel used by the skill installer. Also extend
scripts/tsconfig.json to include globals.d.ts so CLI_VERSION is in
scope when tsc follows the cross-package import.
Remove the PackageManager type re-export from bootstrap-registry and
update consumers (bootstrap.ts, context.ts, index.ts) to import the
type directly from lib/package-manager.ts.
Adds init, apps create, open, completion, and skill install to the
Core commands table; adds --destructive to config patch/put; clarifies
config put semantics. Strengthens the Prerequisites section to make
'clerk doctor --json' the mandatory session-start check, with a note
to rerun 'clerk skill install' after upgrading the CLI so the bundled
skill matches the new binary.
Adds agent-mode behavior rows for 'apps create' (requires explicit
--json) and 'clerk open' (emits a JSON descriptor instead of launching
a browser), plus matching entries in the structured-outputs table.
Calls out 'clerk <command> --help' as the source of truth for flags so
the skill stays a hint rather than a spec, reducing drift surface.
Hidden commands (deploy, switch-env) remain undocumented.
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.
The bundled clerk skill drifted from the CLI source in a few places.
This commit resyncs the command reference and agent-mode docs:
- `clerk init`: document `--app` (skips interactive picker)
- `clerk config patch`/`put`: document `--app` and `--instance`
- Add `clerk update` row to the core commands table
- `references/agent-mode.md`: document the structured JSON error
output (`{"error":{...}}` on stderr) that agent mode emits, split
error-format guidance into human vs agent columns
- SKILL.md: expand the `clerk doctor --json` shape to include
`detail` and `fix` alongside `remedy`
Correct documentation drift identified by skill audit:
- OpenAPI catalog cache TTL is 1 hour, not 24 hours (matches
CACHE_TTL_MS in packages/cli-core/src/lib/constants.ts).
- `apps create` auto-emits JSON in agent mode via the shared
printJson() helper, same as `apps list`; update agent-mode matrix
and SKILL.md bullet so agents don't unnecessarily add --json.
Pull the accurate, CLI-verified additions from the external clerk-cli skill
draft into the bundled clerk skill:
- Document auth aliases: signup/signin/sign-in, signout/sign-out, and the
top-level clerk login / clerk logout shortcuts.
- Explain --destructive on config patch (same semantics as on config put).
- Note that config commands authenticate via the Platform API and do not
accept --secret-key.
- Add a mapping from each failing clerk doctor check to the manual
remediation command (auth login / link / env pull), since doctor --fix
is disabled in agent mode.
PR #29 items skipped because they drift from the current CLI source:
the {checks, overall} doctor JSON wrapper (actual output is a flat array)
and doctor --fix working in agent mode (source gates it on isHuman()).
Co-authored-by: Rafael Thayto <rafa.thayto@gmail.com>
Replace hardcoded ~/.clerk/config.json and ~/.clerk/cache/ paths with
platform-agnostic guidance since constants.ts uses envPaths (XDG). Add
CLERK_CONFIG_DIR to the environment variables table.
- Remove "clerk" from BASE_SKILLS so the upstream clerk/skills install
no longer overwrites the bundled pinned skill
- Import DEV_CLI_VERSION in update-check.ts to eliminate duplicate sentinel
- Move detectPackageManager to lib/package-manager; re-export from context
- Expand version substitution tests to cover all 4 bundled skill files
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch from a1a52fd to 6d0ef8aCompareApril 20, 2026 15:00
@wyattjoh
wyattjoh merged commit 8c02278 into mainApr 20, 2026
10 checks passed
@wyattjoh
wyattjoh deleted the feat/clerk-cli-skill-pinned branch April 20, 2026 17:54
@github-actionsgithub-actionsBot mentioned this pull request Apr 20, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@wyattjoh@rafa-thayto
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' feat: Clerk CLI Skill by wyattjoh · Pull Request #126 · clerk/cli · GitHub
Skip to content

feat: Clerk CLI Skill - #126

Merged
wyattjoh merged 19 commits into
mainfrom
feat/clerk-cli-skill-pinned
Apr 20, 2026
Merged

feat: Clerk CLI Skill#126
wyattjoh merged 19 commits into
mainfrom
feat/clerk-cli-skill-pinned

Conversation

@wyattjoh

@wyattjohwyattjoh commented Apr 7, 2026

Copy link
Copy Markdown
Contributor

Summary

Bundles the clerk skill into the CLI binary, pins it to the version of the binary that installed it, and teaches the skill how to invoke clerk using whatever runner the project prefers.

How it's bundled

  • Markdown files at <repo-root>/skills/clerk/ are pulled into skills.ts as text imports (import md from "./SKILL.md" with { type: "text" }). These resolve live during bun run dev and get embedded by bun build --compile, so the skill content always matches the binary running it.
  • At install time, the staged bundle is handed to <runner> skills add <tmpdir> --copy. --copy is required: the default symlink mode would point each agent's skill dir at the temp dir we delete right after the install.
  • skills-lock.json records the install with sourceType: "local", correctly excluding it from skills update. The skill can only change when the CLI is upgraded.

How it pins

  • Every asset is piped through a new renderSkillVersionPlaceholder(content, version) helper that substitutes {{CLI_VERSION}} at staging time. Release builds pin to the shipped version; dev builds (0.0.0-dev) resolve to latest.
  • DEV_CLI_VERSION and resolveCliVersion() live in a new lib/version.ts so the three sites that care about the dev sentinel (the --version fallback, the skill templater, and scripts/build.ts) share one source of truth and can't drift.

How the skill invokes clerk

A new "Invoking the CLI" section in SKILL.md teaches Claude to prefer a globally installed clerk binary first, and fall back to a pinned bunx / npx -y / pnpm dlx / yarn dlx in lockfile-preferred order. Mirrors the CLI's own preferredRunner logic.

Skill correctness

  • Removes a wrong claim that clerk init --prompt prints a framework-specific integration guide. It prints a short agent handoff telling the agent to run clerk init -y.
  • Resyncs the skill against the current CLI surface: adds init, apps create, open, completion, and skill install to the Core commands table; adds --destructive to config patch/put; strengthens the Prerequisites section so clerk doctor --json is the mandatory session-start check; documents agent-mode behavior for apps create and clerk open.
  • Adds --name (with --starter) to the init row and --secret-key to the api row in the Core commands table, and corrects the clerk api ls --platform apps example (dropped an erroneous --).
  • Repositions clerk <command> --help as the source of truth for flags so the skill stays a hint rather than a spec, reducing drift surface.
  • Ports useful additions from feat(clerk-cli): add Clerk CLI skill skills#29 (verified against CLI source): documents the clerk auth login/logout aliases (signup/signin/sign-in, signout/sign-out) and the top-level clerk login/clerk logout shortcuts; notes that config commands authenticate via the Platform API and ignore --secret-key; extends the --destructive explanation to config patch (same semantics as config put); adds a table mapping each failing clerk doctor check to the manual remediation command (auth login / link / env pull) so agents can remediate without --fix (which is disabled in agent mode).

Skill rename

The bundled skill is named clerk (directory: skills/clerk/, frontmatter name: clerk). CLI-level identifiers that ship to user state (macOS KEYCHAIN_SERVICE, envPaths config/cache dir) keep the clerk-cli name to avoid orphaning existing installs on upgrade.

Installer continuity

  • Upstream clerk/skills continues to install via default symlink mode; the two installer calls share runner detection and fail independently.
  • buildSkillsArgs gains a copy parameter and threads it through runSkillsAdd so only the clerk skill install gets --copy.

Stacked on #125.

Test plan

  • bun run test passes (unit tests cover buildSkillsArgs--copy, renderSkillVersionPlaceholder edge cases, and withStagedClerkSkill staging + cleanup + version rendering)
  • Manual: run clerk init in a sandbox; confirm clerk and framework-pattern installs both succeed; check skills-lock.json records clerk with sourceType: "local"
  • Manual: confirm .claude/skills/clerk/ contains real files (not a broken symlink) after init
  • Manual: confirm the installed SKILL.md no longer contains the literal {{CLI_VERSION}} after install

@wyattjoh

wyattjoh commented Apr 7, 2026

Copy link
Copy Markdown
ContributorAuthor

@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch from 40b1139 to 2b430c5CompareApril 7, 2026 19:40
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch from 26405f7 to 1e94859CompareApril 7, 2026 19:40
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch from 2b430c5 to bd75724CompareApril 7, 2026 20:23
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch from 1e94859 to 670617fCompareApril 7, 2026 20:23
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch from bd75724 to 510829cCompareApril 7, 2026 21:58
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch 2 times, most recently from 10da1db to a4185bbCompareApril 8, 2026 21:39
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch 2 times, most recently from dae4ecc to 75f79d4CompareApril 9, 2026 20:23
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch 2 times, most recently from a45b262 to c95a429CompareApril 9, 2026 22:54
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch from 75f79d4 to 2bc5f72CompareApril 9, 2026 22:54
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch from c95a429 to 79d474fCompareApril 11, 2026 06:48
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch from 2bc5f72 to c52bc3fCompareApril 11, 2026 06:48
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch from 79d474f to 08653a1CompareApril 11, 2026 06:54
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch from c52bc3f to 27b5058CompareApril 11, 2026 06:54
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch from 08653a1 to a8903e7CompareApril 13, 2026 20:01
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch 2 times, most recently from f0d314f to 8e087a7CompareApril 13, 2026 22:49
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch from a8903e7 to 190c5d5CompareApril 13, 2026 22:49
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch from 8e087a7 to 13e75abCompareApril 13, 2026 23:20
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch from 190c5d5 to 09c9f9bCompareApril 13, 2026 23:20
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch from 13e75ab to 7154722CompareApril 14, 2026 18:50
@wyattjohwyattjoh changed the title feat(init): version-pinned clerk-cli skill installerfeat(init): bundle clerk-cli skill into the binaryApr 14, 2026
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch from 09c9f9b to 59ca3dbCompareApril 14, 2026 18:56
Comment threadpackages/cli-core/src/commands/init/skills.ts
Comment threadpackages/cli-core/src/lib/version.ts
Comment threadpackages/cli-core/src/commands/skill/install.ts Outdated
Comment threadpackages/cli-core/src/commands/skill/install.test.ts
wyattjohand others added 19 commits April 20, 2026 09:00
Pulls the clerk-cli skill markdown files at <repo-root>/skills/clerk-cli/
into skills.ts as text imports (`import md from "./SKILL.md" with { type:
"text" }`), which resolve live during `bun run dev` and get embedded by
`bun build --compile`. The skill content therefore always matches the
binary running it, with no network lookup, no tag publishing race, and
no CLI_VERSION URL fallback.
At install time, `installSkills` stages the bundled content into a fresh
`mkdtemp` directory and invokes `<runner> skills add <tmpdir> --copy`.
The --copy flag is required: the `skills` CLI's default symlink mode
would point each agent's skill dir at the temp dir, which we delete
immediately after the install completes. Copy mode produces real files
in `.claude/skills/clerk-cli/` etc. and records the install 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).
The upstream `clerk/skills` install continues to use the default symlink
mode against the remote source. The two installer calls share one
runner detection and fail independently.
Installs the bundled clerk-cli skill standalone so projects set up before
the skill was bundled, or CLIs upgraded since, can pull it in without
re-running init. `init` now delegates the clerk-cli portion to shared
core in commands/skill/install.ts, keeping a single runner detection
across clerk-cli and upstream framework skills.
Also extracts PACKAGE_MANAGERS as the canonical tuple plus derived type
in lib/package-manager.ts, reused by both `init --pm` and
`skill install --pm` choices. PM_PRIORITY in bootstrap keeps its
semantic name via `satisfies readonly PackageManager[]` plus a
compile-time exhaustiveness guard.
Fix the nano-staged oxlint hook to pass `-c .oxlintrc.json` explicitly
so override files (e.g. `unicorn/no-process-exit` off in cli-program.ts)
apply when linting specific paths; bare `oxlint <file>` does not
auto-discover the config.
Hoists the dev-version sentinel to a shared lib/version module so
cli-program.ts and install.ts stay in lockstep. Adds resolveCliVersion()
which maps both undefined and the 0.0.0-dev sentinel to undefined, letting
downstream callers treat unversioned binaries uniformly.
Threads the resolved version through withStagedClerkCliSkill so every
bundled asset has {{CLI_VERSION}} substituted at install time. The install
caller uses resolveCliVersion() instead of an inline typeof guard.
Import DEV_CLI_VERSION from packages/cli-core/src/lib/version.ts in
scripts/build.ts so the build script's default version arg stays in
lockstep with the sentinel used by the skill installer. Also extend
scripts/tsconfig.json to include globals.d.ts so CLI_VERSION is in
scope when tsc follows the cross-package import.
Remove the PackageManager type re-export from bootstrap-registry and
update consumers (bootstrap.ts, context.ts, index.ts) to import the
type directly from lib/package-manager.ts.
Adds init, apps create, open, completion, and skill install to the
Core commands table; adds --destructive to config patch/put; clarifies
config put semantics. Strengthens the Prerequisites section to make
'clerk doctor --json' the mandatory session-start check, with a note
to rerun 'clerk skill install' after upgrading the CLI so the bundled
skill matches the new binary.
Adds agent-mode behavior rows for 'apps create' (requires explicit
--json) and 'clerk open' (emits a JSON descriptor instead of launching
a browser), plus matching entries in the structured-outputs table.
Calls out 'clerk <command> --help' as the source of truth for flags so
the skill stays a hint rather than a spec, reducing drift surface.
Hidden commands (deploy, switch-env) remain undocumented.
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.
The bundled clerk skill drifted from the CLI source in a few places.
This commit resyncs the command reference and agent-mode docs:
- `clerk init`: document `--app` (skips interactive picker)
- `clerk config patch`/`put`: document `--app` and `--instance`
- Add `clerk update` row to the core commands table
- `references/agent-mode.md`: document the structured JSON error
output (`{"error":{...}}` on stderr) that agent mode emits, split
error-format guidance into human vs agent columns
- SKILL.md: expand the `clerk doctor --json` shape to include
`detail` and `fix` alongside `remedy`
Correct documentation drift identified by skill audit:
- OpenAPI catalog cache TTL is 1 hour, not 24 hours (matches
CACHE_TTL_MS in packages/cli-core/src/lib/constants.ts).
- `apps create` auto-emits JSON in agent mode via the shared
printJson() helper, same as `apps list`; update agent-mode matrix
and SKILL.md bullet so agents don't unnecessarily add --json.
Pull the accurate, CLI-verified additions from the external clerk-cli skill
draft into the bundled clerk skill:
- Document auth aliases: signup/signin/sign-in, signout/sign-out, and the
top-level clerk login / clerk logout shortcuts.
- Explain --destructive on config patch (same semantics as on config put).
- Note that config commands authenticate via the Platform API and do not
accept --secret-key.
- Add a mapping from each failing clerk doctor check to the manual
remediation command (auth login / link / env pull), since doctor --fix
is disabled in agent mode.
PR #29 items skipped because they drift from the current CLI source:
the {checks, overall} doctor JSON wrapper (actual output is a flat array)
and doctor --fix working in agent mode (source gates it on isHuman()).
Co-authored-by: Rafael Thayto <rafa.thayto@gmail.com>
Replace hardcoded ~/.clerk/config.json and ~/.clerk/cache/ paths with
platform-agnostic guidance since constants.ts uses envPaths (XDG). Add
CLERK_CONFIG_DIR to the environment variables table.
- Remove "clerk" from BASE_SKILLS so the upstream clerk/skills install
no longer overwrites the bundled pinned skill
- Import DEV_CLI_VERSION in update-check.ts to eliminate duplicate sentinel
- Move detectPackageManager to lib/package-manager; re-export from context
- Expand version substitution tests to cover all 4 bundled skill files
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch from a1a52fd to 6d0ef8aCompareApril 20, 2026 15:00
@wyattjoh
wyattjoh merged commit 8c02278 into mainApr 20, 2026
10 checks passed
@wyattjoh
wyattjoh deleted the feat/clerk-cli-skill-pinned branch April 20, 2026 17:54
@github-actionsgithub-actionsBot mentioned this pull request Apr 20, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@wyattjoh@rafa-thayto
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' feat: Clerk CLI Skill by wyattjoh · Pull Request #126 · clerk/cli · GitHub
Skip to content

feat: Clerk CLI Skill - #126

Merged
wyattjoh merged 19 commits into
mainfrom
feat/clerk-cli-skill-pinned
Apr 20, 2026
Merged

feat: Clerk CLI Skill#126
wyattjoh merged 19 commits into
mainfrom
feat/clerk-cli-skill-pinned

Conversation

@wyattjoh

@wyattjohwyattjoh commented Apr 7, 2026

Copy link
Copy Markdown
Contributor

Summary

Bundles the clerk skill into the CLI binary, pins it to the version of the binary that installed it, and teaches the skill how to invoke clerk using whatever runner the project prefers.

How it's bundled

  • Markdown files at <repo-root>/skills/clerk/ are pulled into skills.ts as text imports (import md from "./SKILL.md" with { type: "text" }). These resolve live during bun run dev and get embedded by bun build --compile, so the skill content always matches the binary running it.
  • At install time, the staged bundle is handed to <runner> skills add <tmpdir> --copy. --copy is required: the default symlink mode would point each agent's skill dir at the temp dir we delete right after the install.
  • skills-lock.json records the install with sourceType: "local", correctly excluding it from skills update. The skill can only change when the CLI is upgraded.

How it pins

  • Every asset is piped through a new renderSkillVersionPlaceholder(content, version) helper that substitutes {{CLI_VERSION}} at staging time. Release builds pin to the shipped version; dev builds (0.0.0-dev) resolve to latest.
  • DEV_CLI_VERSION and resolveCliVersion() live in a new lib/version.ts so the three sites that care about the dev sentinel (the --version fallback, the skill templater, and scripts/build.ts) share one source of truth and can't drift.

How the skill invokes clerk

A new "Invoking the CLI" section in SKILL.md teaches Claude to prefer a globally installed clerk binary first, and fall back to a pinned bunx / npx -y / pnpm dlx / yarn dlx in lockfile-preferred order. Mirrors the CLI's own preferredRunner logic.

Skill correctness

  • Removes a wrong claim that clerk init --prompt prints a framework-specific integration guide. It prints a short agent handoff telling the agent to run clerk init -y.
  • Resyncs the skill against the current CLI surface: adds init, apps create, open, completion, and skill install to the Core commands table; adds --destructive to config patch/put; strengthens the Prerequisites section so clerk doctor --json is the mandatory session-start check; documents agent-mode behavior for apps create and clerk open.
  • Adds --name (with --starter) to the init row and --secret-key to the api row in the Core commands table, and corrects the clerk api ls --platform apps example (dropped an erroneous --).
  • Repositions clerk <command> --help as the source of truth for flags so the skill stays a hint rather than a spec, reducing drift surface.
  • Ports useful additions from feat(clerk-cli): add Clerk CLI skill skills#29 (verified against CLI source): documents the clerk auth login/logout aliases (signup/signin/sign-in, signout/sign-out) and the top-level clerk login/clerk logout shortcuts; notes that config commands authenticate via the Platform API and ignore --secret-key; extends the --destructive explanation to config patch (same semantics as config put); adds a table mapping each failing clerk doctor check to the manual remediation command (auth login / link / env pull) so agents can remediate without --fix (which is disabled in agent mode).

Skill rename

The bundled skill is named clerk (directory: skills/clerk/, frontmatter name: clerk). CLI-level identifiers that ship to user state (macOS KEYCHAIN_SERVICE, envPaths config/cache dir) keep the clerk-cli name to avoid orphaning existing installs on upgrade.

Installer continuity

  • Upstream clerk/skills continues to install via default symlink mode; the two installer calls share runner detection and fail independently.
  • buildSkillsArgs gains a copy parameter and threads it through runSkillsAdd so only the clerk skill install gets --copy.

Stacked on #125.

Test plan

  • bun run test passes (unit tests cover buildSkillsArgs--copy, renderSkillVersionPlaceholder edge cases, and withStagedClerkSkill staging + cleanup + version rendering)
  • Manual: run clerk init in a sandbox; confirm clerk and framework-pattern installs both succeed; check skills-lock.json records clerk with sourceType: "local"
  • Manual: confirm .claude/skills/clerk/ contains real files (not a broken symlink) after init
  • Manual: confirm the installed SKILL.md no longer contains the literal {{CLI_VERSION}} after install

@wyattjoh

wyattjoh commented Apr 7, 2026

Copy link
Copy Markdown
ContributorAuthor

@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch from 40b1139 to 2b430c5CompareApril 7, 2026 19:40
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch from 26405f7 to 1e94859CompareApril 7, 2026 19:40
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch from 2b430c5 to bd75724CompareApril 7, 2026 20:23
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch from 1e94859 to 670617fCompareApril 7, 2026 20:23
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch from bd75724 to 510829cCompareApril 7, 2026 21:58
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch 2 times, most recently from 10da1db to a4185bbCompareApril 8, 2026 21:39
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch 2 times, most recently from dae4ecc to 75f79d4CompareApril 9, 2026 20:23
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch 2 times, most recently from a45b262 to c95a429CompareApril 9, 2026 22:54
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch from 75f79d4 to 2bc5f72CompareApril 9, 2026 22:54
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch from c95a429 to 79d474fCompareApril 11, 2026 06:48
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch from 2bc5f72 to c52bc3fCompareApril 11, 2026 06:48
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch from 79d474f to 08653a1CompareApril 11, 2026 06:54
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch from c52bc3f to 27b5058CompareApril 11, 2026 06:54
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch from 08653a1 to a8903e7CompareApril 13, 2026 20:01
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch 2 times, most recently from f0d314f to 8e087a7CompareApril 13, 2026 22:49
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch from a8903e7 to 190c5d5CompareApril 13, 2026 22:49
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch from 8e087a7 to 13e75abCompareApril 13, 2026 23:20
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch from 190c5d5 to 09c9f9bCompareApril 13, 2026 23:20
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch from 13e75ab to 7154722CompareApril 14, 2026 18:50
@wyattjohwyattjoh changed the title feat(init): version-pinned clerk-cli skill installerfeat(init): bundle clerk-cli skill into the binaryApr 14, 2026
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch from 09c9f9b to 59ca3dbCompareApril 14, 2026 18:56
Comment threadpackages/cli-core/src/commands/init/skills.ts
Comment threadpackages/cli-core/src/lib/version.ts
Comment threadpackages/cli-core/src/commands/skill/install.ts Outdated
Comment threadpackages/cli-core/src/commands/skill/install.test.ts
wyattjohand others added 19 commits April 20, 2026 09:00
Pulls the clerk-cli skill markdown files at <repo-root>/skills/clerk-cli/
into skills.ts as text imports (`import md from "./SKILL.md" with { type:
"text" }`), which resolve live during `bun run dev` and get embedded by
`bun build --compile`. The skill content therefore always matches the
binary running it, with no network lookup, no tag publishing race, and
no CLI_VERSION URL fallback.
At install time, `installSkills` stages the bundled content into a fresh
`mkdtemp` directory and invokes `<runner> skills add <tmpdir> --copy`.
The --copy flag is required: the `skills` CLI's default symlink mode
would point each agent's skill dir at the temp dir, which we delete
immediately after the install completes. Copy mode produces real files
in `.claude/skills/clerk-cli/` etc. and records the install 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).
The upstream `clerk/skills` install continues to use the default symlink
mode against the remote source. The two installer calls share one
runner detection and fail independently.
Installs the bundled clerk-cli skill standalone so projects set up before
the skill was bundled, or CLIs upgraded since, can pull it in without
re-running init. `init` now delegates the clerk-cli portion to shared
core in commands/skill/install.ts, keeping a single runner detection
across clerk-cli and upstream framework skills.
Also extracts PACKAGE_MANAGERS as the canonical tuple plus derived type
in lib/package-manager.ts, reused by both `init --pm` and
`skill install --pm` choices. PM_PRIORITY in bootstrap keeps its
semantic name via `satisfies readonly PackageManager[]` plus a
compile-time exhaustiveness guard.
Fix the nano-staged oxlint hook to pass `-c .oxlintrc.json` explicitly
so override files (e.g. `unicorn/no-process-exit` off in cli-program.ts)
apply when linting specific paths; bare `oxlint <file>` does not
auto-discover the config.
Hoists the dev-version sentinel to a shared lib/version module so
cli-program.ts and install.ts stay in lockstep. Adds resolveCliVersion()
which maps both undefined and the 0.0.0-dev sentinel to undefined, letting
downstream callers treat unversioned binaries uniformly.
Threads the resolved version through withStagedClerkCliSkill so every
bundled asset has {{CLI_VERSION}} substituted at install time. The install
caller uses resolveCliVersion() instead of an inline typeof guard.
Import DEV_CLI_VERSION from packages/cli-core/src/lib/version.ts in
scripts/build.ts so the build script's default version arg stays in
lockstep with the sentinel used by the skill installer. Also extend
scripts/tsconfig.json to include globals.d.ts so CLI_VERSION is in
scope when tsc follows the cross-package import.
Remove the PackageManager type re-export from bootstrap-registry and
update consumers (bootstrap.ts, context.ts, index.ts) to import the
type directly from lib/package-manager.ts.
Adds init, apps create, open, completion, and skill install to the
Core commands table; adds --destructive to config patch/put; clarifies
config put semantics. Strengthens the Prerequisites section to make
'clerk doctor --json' the mandatory session-start check, with a note
to rerun 'clerk skill install' after upgrading the CLI so the bundled
skill matches the new binary.
Adds agent-mode behavior rows for 'apps create' (requires explicit
--json) and 'clerk open' (emits a JSON descriptor instead of launching
a browser), plus matching entries in the structured-outputs table.
Calls out 'clerk <command> --help' as the source of truth for flags so
the skill stays a hint rather than a spec, reducing drift surface.
Hidden commands (deploy, switch-env) remain undocumented.
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.
The bundled clerk skill drifted from the CLI source in a few places.
This commit resyncs the command reference and agent-mode docs:
- `clerk init`: document `--app` (skips interactive picker)
- `clerk config patch`/`put`: document `--app` and `--instance`
- Add `clerk update` row to the core commands table
- `references/agent-mode.md`: document the structured JSON error
output (`{"error":{...}}` on stderr) that agent mode emits, split
error-format guidance into human vs agent columns
- SKILL.md: expand the `clerk doctor --json` shape to include
`detail` and `fix` alongside `remedy`
Correct documentation drift identified by skill audit:
- OpenAPI catalog cache TTL is 1 hour, not 24 hours (matches
CACHE_TTL_MS in packages/cli-core/src/lib/constants.ts).
- `apps create` auto-emits JSON in agent mode via the shared
printJson() helper, same as `apps list`; update agent-mode matrix
and SKILL.md bullet so agents don't unnecessarily add --json.
Pull the accurate, CLI-verified additions from the external clerk-cli skill
draft into the bundled clerk skill:
- Document auth aliases: signup/signin/sign-in, signout/sign-out, and the
top-level clerk login / clerk logout shortcuts.
- Explain --destructive on config patch (same semantics as on config put).
- Note that config commands authenticate via the Platform API and do not
accept --secret-key.
- Add a mapping from each failing clerk doctor check to the manual
remediation command (auth login / link / env pull), since doctor --fix
is disabled in agent mode.
PR #29 items skipped because they drift from the current CLI source:
the {checks, overall} doctor JSON wrapper (actual output is a flat array)
and doctor --fix working in agent mode (source gates it on isHuman()).
Co-authored-by: Rafael Thayto <rafa.thayto@gmail.com>
Replace hardcoded ~/.clerk/config.json and ~/.clerk/cache/ paths with
platform-agnostic guidance since constants.ts uses envPaths (XDG). Add
CLERK_CONFIG_DIR to the environment variables table.
- Remove "clerk" from BASE_SKILLS so the upstream clerk/skills install
no longer overwrites the bundled pinned skill
- Import DEV_CLI_VERSION in update-check.ts to eliminate duplicate sentinel
- Move detectPackageManager to lib/package-manager; re-export from context
- Expand version substitution tests to cover all 4 bundled skill files
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch from a1a52fd to 6d0ef8aCompareApril 20, 2026 15:00
@wyattjoh
wyattjoh merged commit 8c02278 into mainApr 20, 2026
10 checks passed
@wyattjoh
wyattjoh deleted the feat/clerk-cli-skill-pinned branch April 20, 2026 17:54
@github-actionsgithub-actionsBot mentioned this pull request Apr 20, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@wyattjoh@rafa-thayto
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' feat: Clerk CLI Skill by wyattjoh · Pull Request #126 · clerk/cli · GitHub
Skip to content

feat: Clerk CLI Skill - #126

Merged
wyattjoh merged 19 commits into
mainfrom
feat/clerk-cli-skill-pinned
Apr 20, 2026
Merged

feat: Clerk CLI Skill#126
wyattjoh merged 19 commits into
mainfrom
feat/clerk-cli-skill-pinned

Conversation

@wyattjoh

@wyattjohwyattjoh commented Apr 7, 2026

Copy link
Copy Markdown
Contributor

Summary

Bundles the clerk skill into the CLI binary, pins it to the version of the binary that installed it, and teaches the skill how to invoke clerk using whatever runner the project prefers.

How it's bundled

  • Markdown files at <repo-root>/skills/clerk/ are pulled into skills.ts as text imports (import md from "./SKILL.md" with { type: "text" }). These resolve live during bun run dev and get embedded by bun build --compile, so the skill content always matches the binary running it.
  • At install time, the staged bundle is handed to <runner> skills add <tmpdir> --copy. --copy is required: the default symlink mode would point each agent's skill dir at the temp dir we delete right after the install.
  • skills-lock.json records the install with sourceType: "local", correctly excluding it from skills update. The skill can only change when the CLI is upgraded.

How it pins

  • Every asset is piped through a new renderSkillVersionPlaceholder(content, version) helper that substitutes {{CLI_VERSION}} at staging time. Release builds pin to the shipped version; dev builds (0.0.0-dev) resolve to latest.
  • DEV_CLI_VERSION and resolveCliVersion() live in a new lib/version.ts so the three sites that care about the dev sentinel (the --version fallback, the skill templater, and scripts/build.ts) share one source of truth and can't drift.

How the skill invokes clerk

A new "Invoking the CLI" section in SKILL.md teaches Claude to prefer a globally installed clerk binary first, and fall back to a pinned bunx / npx -y / pnpm dlx / yarn dlx in lockfile-preferred order. Mirrors the CLI's own preferredRunner logic.

Skill correctness

  • Removes a wrong claim that clerk init --prompt prints a framework-specific integration guide. It prints a short agent handoff telling the agent to run clerk init -y.
  • Resyncs the skill against the current CLI surface: adds init, apps create, open, completion, and skill install to the Core commands table; adds --destructive to config patch/put; strengthens the Prerequisites section so clerk doctor --json is the mandatory session-start check; documents agent-mode behavior for apps create and clerk open.
  • Adds --name (with --starter) to the init row and --secret-key to the api row in the Core commands table, and corrects the clerk api ls --platform apps example (dropped an erroneous --).
  • Repositions clerk <command> --help as the source of truth for flags so the skill stays a hint rather than a spec, reducing drift surface.
  • Ports useful additions from feat(clerk-cli): add Clerk CLI skill skills#29 (verified against CLI source): documents the clerk auth login/logout aliases (signup/signin/sign-in, signout/sign-out) and the top-level clerk login/clerk logout shortcuts; notes that config commands authenticate via the Platform API and ignore --secret-key; extends the --destructive explanation to config patch (same semantics as config put); adds a table mapping each failing clerk doctor check to the manual remediation command (auth login / link / env pull) so agents can remediate without --fix (which is disabled in agent mode).

Skill rename

The bundled skill is named clerk (directory: skills/clerk/, frontmatter name: clerk). CLI-level identifiers that ship to user state (macOS KEYCHAIN_SERVICE, envPaths config/cache dir) keep the clerk-cli name to avoid orphaning existing installs on upgrade.

Installer continuity

  • Upstream clerk/skills continues to install via default symlink mode; the two installer calls share runner detection and fail independently.
  • buildSkillsArgs gains a copy parameter and threads it through runSkillsAdd so only the clerk skill install gets --copy.

Stacked on #125.

Test plan

  • bun run test passes (unit tests cover buildSkillsArgs--copy, renderSkillVersionPlaceholder edge cases, and withStagedClerkSkill staging + cleanup + version rendering)
  • Manual: run clerk init in a sandbox; confirm clerk and framework-pattern installs both succeed; check skills-lock.json records clerk with sourceType: "local"
  • Manual: confirm .claude/skills/clerk/ contains real files (not a broken symlink) after init
  • Manual: confirm the installed SKILL.md no longer contains the literal {{CLI_VERSION}} after install

@wyattjoh

wyattjoh commented Apr 7, 2026

Copy link
Copy Markdown
ContributorAuthor

@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch from 40b1139 to 2b430c5CompareApril 7, 2026 19:40
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch from 26405f7 to 1e94859CompareApril 7, 2026 19:40
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch from 2b430c5 to bd75724CompareApril 7, 2026 20:23
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch from 1e94859 to 670617fCompareApril 7, 2026 20:23
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch from bd75724 to 510829cCompareApril 7, 2026 21:58
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch 2 times, most recently from 10da1db to a4185bbCompareApril 8, 2026 21:39
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch 2 times, most recently from dae4ecc to 75f79d4CompareApril 9, 2026 20:23
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch 2 times, most recently from a45b262 to c95a429CompareApril 9, 2026 22:54
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch from 75f79d4 to 2bc5f72CompareApril 9, 2026 22:54
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch from c95a429 to 79d474fCompareApril 11, 2026 06:48
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch from 2bc5f72 to c52bc3fCompareApril 11, 2026 06:48
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch from 79d474f to 08653a1CompareApril 11, 2026 06:54
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch from c52bc3f to 27b5058CompareApril 11, 2026 06:54
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch from 08653a1 to a8903e7CompareApril 13, 2026 20:01
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch 2 times, most recently from f0d314f to 8e087a7CompareApril 13, 2026 22:49
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch from a8903e7 to 190c5d5CompareApril 13, 2026 22:49
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch from 8e087a7 to 13e75abCompareApril 13, 2026 23:20
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch from 190c5d5 to 09c9f9bCompareApril 13, 2026 23:20
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch from 13e75ab to 7154722CompareApril 14, 2026 18:50
@wyattjohwyattjoh changed the title feat(init): version-pinned clerk-cli skill installerfeat(init): bundle clerk-cli skill into the binaryApr 14, 2026
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch from 09c9f9b to 59ca3dbCompareApril 14, 2026 18:56
Comment threadpackages/cli-core/src/commands/init/skills.ts
Comment threadpackages/cli-core/src/lib/version.ts
Comment threadpackages/cli-core/src/commands/skill/install.ts Outdated
Comment threadpackages/cli-core/src/commands/skill/install.test.ts
wyattjohand others added 19 commits April 20, 2026 09:00
Pulls the clerk-cli skill markdown files at <repo-root>/skills/clerk-cli/
into skills.ts as text imports (`import md from "./SKILL.md" with { type:
"text" }`), which resolve live during `bun run dev` and get embedded by
`bun build --compile`. The skill content therefore always matches the
binary running it, with no network lookup, no tag publishing race, and
no CLI_VERSION URL fallback.
At install time, `installSkills` stages the bundled content into a fresh
`mkdtemp` directory and invokes `<runner> skills add <tmpdir> --copy`.
The --copy flag is required: the `skills` CLI's default symlink mode
would point each agent's skill dir at the temp dir, which we delete
immediately after the install completes. Copy mode produces real files
in `.claude/skills/clerk-cli/` etc. and records the install 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).
The upstream `clerk/skills` install continues to use the default symlink
mode against the remote source. The two installer calls share one
runner detection and fail independently.
Installs the bundled clerk-cli skill standalone so projects set up before
the skill was bundled, or CLIs upgraded since, can pull it in without
re-running init. `init` now delegates the clerk-cli portion to shared
core in commands/skill/install.ts, keeping a single runner detection
across clerk-cli and upstream framework skills.
Also extracts PACKAGE_MANAGERS as the canonical tuple plus derived type
in lib/package-manager.ts, reused by both `init --pm` and
`skill install --pm` choices. PM_PRIORITY in bootstrap keeps its
semantic name via `satisfies readonly PackageManager[]` plus a
compile-time exhaustiveness guard.
Fix the nano-staged oxlint hook to pass `-c .oxlintrc.json` explicitly
so override files (e.g. `unicorn/no-process-exit` off in cli-program.ts)
apply when linting specific paths; bare `oxlint <file>` does not
auto-discover the config.
Hoists the dev-version sentinel to a shared lib/version module so
cli-program.ts and install.ts stay in lockstep. Adds resolveCliVersion()
which maps both undefined and the 0.0.0-dev sentinel to undefined, letting
downstream callers treat unversioned binaries uniformly.
Threads the resolved version through withStagedClerkCliSkill so every
bundled asset has {{CLI_VERSION}} substituted at install time. The install
caller uses resolveCliVersion() instead of an inline typeof guard.
Import DEV_CLI_VERSION from packages/cli-core/src/lib/version.ts in
scripts/build.ts so the build script's default version arg stays in
lockstep with the sentinel used by the skill installer. Also extend
scripts/tsconfig.json to include globals.d.ts so CLI_VERSION is in
scope when tsc follows the cross-package import.
Remove the PackageManager type re-export from bootstrap-registry and
update consumers (bootstrap.ts, context.ts, index.ts) to import the
type directly from lib/package-manager.ts.
Adds init, apps create, open, completion, and skill install to the
Core commands table; adds --destructive to config patch/put; clarifies
config put semantics. Strengthens the Prerequisites section to make
'clerk doctor --json' the mandatory session-start check, with a note
to rerun 'clerk skill install' after upgrading the CLI so the bundled
skill matches the new binary.
Adds agent-mode behavior rows for 'apps create' (requires explicit
--json) and 'clerk open' (emits a JSON descriptor instead of launching
a browser), plus matching entries in the structured-outputs table.
Calls out 'clerk <command> --help' as the source of truth for flags so
the skill stays a hint rather than a spec, reducing drift surface.
Hidden commands (deploy, switch-env) remain undocumented.
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.
The bundled clerk skill drifted from the CLI source in a few places.
This commit resyncs the command reference and agent-mode docs:
- `clerk init`: document `--app` (skips interactive picker)
- `clerk config patch`/`put`: document `--app` and `--instance`
- Add `clerk update` row to the core commands table
- `references/agent-mode.md`: document the structured JSON error
output (`{"error":{...}}` on stderr) that agent mode emits, split
error-format guidance into human vs agent columns
- SKILL.md: expand the `clerk doctor --json` shape to include
`detail` and `fix` alongside `remedy`
Correct documentation drift identified by skill audit:
- OpenAPI catalog cache TTL is 1 hour, not 24 hours (matches
CACHE_TTL_MS in packages/cli-core/src/lib/constants.ts).
- `apps create` auto-emits JSON in agent mode via the shared
printJson() helper, same as `apps list`; update agent-mode matrix
and SKILL.md bullet so agents don't unnecessarily add --json.
Pull the accurate, CLI-verified additions from the external clerk-cli skill
draft into the bundled clerk skill:
- Document auth aliases: signup/signin/sign-in, signout/sign-out, and the
top-level clerk login / clerk logout shortcuts.
- Explain --destructive on config patch (same semantics as on config put).
- Note that config commands authenticate via the Platform API and do not
accept --secret-key.
- Add a mapping from each failing clerk doctor check to the manual
remediation command (auth login / link / env pull), since doctor --fix
is disabled in agent mode.
PR #29 items skipped because they drift from the current CLI source:
the {checks, overall} doctor JSON wrapper (actual output is a flat array)
and doctor --fix working in agent mode (source gates it on isHuman()).
Co-authored-by: Rafael Thayto <rafa.thayto@gmail.com>
Replace hardcoded ~/.clerk/config.json and ~/.clerk/cache/ paths with
platform-agnostic guidance since constants.ts uses envPaths (XDG). Add
CLERK_CONFIG_DIR to the environment variables table.
- Remove "clerk" from BASE_SKILLS so the upstream clerk/skills install
no longer overwrites the bundled pinned skill
- Import DEV_CLI_VERSION in update-check.ts to eliminate duplicate sentinel
- Move detectPackageManager to lib/package-manager; re-export from context
- Expand version substitution tests to cover all 4 bundled skill files
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch from a1a52fd to 6d0ef8aCompareApril 20, 2026 15:00
@wyattjoh
wyattjoh merged commit 8c02278 into mainApr 20, 2026
10 checks passed
@wyattjoh
wyattjoh deleted the feat/clerk-cli-skill-pinned branch April 20, 2026 17:54
@github-actionsgithub-actionsBot mentioned this pull request Apr 20, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@wyattjoh@rafa-thayto
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); feat: Clerk CLI Skill by wyattjoh · Pull Request #126 · clerk/cli · GitHub
Skip to content

feat: Clerk CLI Skill - #126

Merged
wyattjoh merged 19 commits into
mainfrom
feat/clerk-cli-skill-pinned
Apr 20, 2026
Merged

feat: Clerk CLI Skill#126
wyattjoh merged 19 commits into
mainfrom
feat/clerk-cli-skill-pinned

Conversation

@wyattjoh

@wyattjohwyattjoh commented Apr 7, 2026

Copy link
Copy Markdown
Contributor

Summary

Bundles the clerk skill into the CLI binary, pins it to the version of the binary that installed it, and teaches the skill how to invoke clerk using whatever runner the project prefers.

How it's bundled

  • Markdown files at <repo-root>/skills/clerk/ are pulled into skills.ts as text imports (import md from "./SKILL.md" with { type: "text" }). These resolve live during bun run dev and get embedded by bun build --compile, so the skill content always matches the binary running it.
  • At install time, the staged bundle is handed to <runner> skills add <tmpdir> --copy. --copy is required: the default symlink mode would point each agent's skill dir at the temp dir we delete right after the install.
  • skills-lock.json records the install with sourceType: "local", correctly excluding it from skills update. The skill can only change when the CLI is upgraded.

How it pins

  • Every asset is piped through a new renderSkillVersionPlaceholder(content, version) helper that substitutes {{CLI_VERSION}} at staging time. Release builds pin to the shipped version; dev builds (0.0.0-dev) resolve to latest.
  • DEV_CLI_VERSION and resolveCliVersion() live in a new lib/version.ts so the three sites that care about the dev sentinel (the --version fallback, the skill templater, and scripts/build.ts) share one source of truth and can't drift.

How the skill invokes clerk

A new "Invoking the CLI" section in SKILL.md teaches Claude to prefer a globally installed clerk binary first, and fall back to a pinned bunx / npx -y / pnpm dlx / yarn dlx in lockfile-preferred order. Mirrors the CLI's own preferredRunner logic.

Skill correctness

  • Removes a wrong claim that clerk init --prompt prints a framework-specific integration guide. It prints a short agent handoff telling the agent to run clerk init -y.
  • Resyncs the skill against the current CLI surface: adds init, apps create, open, completion, and skill install to the Core commands table; adds --destructive to config patch/put; strengthens the Prerequisites section so clerk doctor --json is the mandatory session-start check; documents agent-mode behavior for apps create and clerk open.
  • Adds --name (with --starter) to the init row and --secret-key to the api row in the Core commands table, and corrects the clerk api ls --platform apps example (dropped an erroneous --).
  • Repositions clerk <command> --help as the source of truth for flags so the skill stays a hint rather than a spec, reducing drift surface.
  • Ports useful additions from feat(clerk-cli): add Clerk CLI skill skills#29 (verified against CLI source): documents the clerk auth login/logout aliases (signup/signin/sign-in, signout/sign-out) and the top-level clerk login/clerk logout shortcuts; notes that config commands authenticate via the Platform API and ignore --secret-key; extends the --destructive explanation to config patch (same semantics as config put); adds a table mapping each failing clerk doctor check to the manual remediation command (auth login / link / env pull) so agents can remediate without --fix (which is disabled in agent mode).

Skill rename

The bundled skill is named clerk (directory: skills/clerk/, frontmatter name: clerk). CLI-level identifiers that ship to user state (macOS KEYCHAIN_SERVICE, envPaths config/cache dir) keep the clerk-cli name to avoid orphaning existing installs on upgrade.

Installer continuity

  • Upstream clerk/skills continues to install via default symlink mode; the two installer calls share runner detection and fail independently.
  • buildSkillsArgs gains a copy parameter and threads it through runSkillsAdd so only the clerk skill install gets --copy.

Stacked on #125.

Test plan

  • bun run test passes (unit tests cover buildSkillsArgs--copy, renderSkillVersionPlaceholder edge cases, and withStagedClerkSkill staging + cleanup + version rendering)
  • Manual: run clerk init in a sandbox; confirm clerk and framework-pattern installs both succeed; check skills-lock.json records clerk with sourceType: "local"
  • Manual: confirm .claude/skills/clerk/ contains real files (not a broken symlink) after init
  • Manual: confirm the installed SKILL.md no longer contains the literal {{CLI_VERSION}} after install

@wyattjoh

wyattjoh commented Apr 7, 2026

Copy link
Copy Markdown
ContributorAuthor

@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch from 40b1139 to 2b430c5CompareApril 7, 2026 19:40
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch from 26405f7 to 1e94859CompareApril 7, 2026 19:40
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch from 2b430c5 to bd75724CompareApril 7, 2026 20:23
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch from 1e94859 to 670617fCompareApril 7, 2026 20:23
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch from bd75724 to 510829cCompareApril 7, 2026 21:58
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch 2 times, most recently from 10da1db to a4185bbCompareApril 8, 2026 21:39
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch 2 times, most recently from dae4ecc to 75f79d4CompareApril 9, 2026 20:23
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch 2 times, most recently from a45b262 to c95a429CompareApril 9, 2026 22:54
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch from 75f79d4 to 2bc5f72CompareApril 9, 2026 22:54
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch from c95a429 to 79d474fCompareApril 11, 2026 06:48
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch from 2bc5f72 to c52bc3fCompareApril 11, 2026 06:48
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch from 79d474f to 08653a1CompareApril 11, 2026 06:54
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch from c52bc3f to 27b5058CompareApril 11, 2026 06:54
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch from 08653a1 to a8903e7CompareApril 13, 2026 20:01
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch 2 times, most recently from f0d314f to 8e087a7CompareApril 13, 2026 22:49
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch from a8903e7 to 190c5d5CompareApril 13, 2026 22:49
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch from 8e087a7 to 13e75abCompareApril 13, 2026 23:20
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch from 190c5d5 to 09c9f9bCompareApril 13, 2026 23:20
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch from 13e75ab to 7154722CompareApril 14, 2026 18:50
@wyattjohwyattjoh changed the title feat(init): version-pinned clerk-cli skill installerfeat(init): bundle clerk-cli skill into the binaryApr 14, 2026
@wyattjoh
wyattjohforce-pushed the feat/lib-non-empty-array branch from 09c9f9b to 59ca3dbCompareApril 14, 2026 18:56
Comment threadpackages/cli-core/src/commands/init/skills.ts
Comment threadpackages/cli-core/src/lib/version.ts
Comment threadpackages/cli-core/src/commands/skill/install.ts Outdated
Comment threadpackages/cli-core/src/commands/skill/install.test.ts
wyattjohand others added 19 commits April 20, 2026 09:00
Pulls the clerk-cli skill markdown files at <repo-root>/skills/clerk-cli/
into skills.ts as text imports (`import md from "./SKILL.md" with { type:
"text" }`), which resolve live during `bun run dev` and get embedded by
`bun build --compile`. The skill content therefore always matches the
binary running it, with no network lookup, no tag publishing race, and
no CLI_VERSION URL fallback.
At install time, `installSkills` stages the bundled content into a fresh
`mkdtemp` directory and invokes `<runner> skills add <tmpdir> --copy`.
The --copy flag is required: the `skills` CLI's default symlink mode
would point each agent's skill dir at the temp dir, which we delete
immediately after the install completes. Copy mode produces real files
in `.claude/skills/clerk-cli/` etc. and records the install 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).
The upstream `clerk/skills` install continues to use the default symlink
mode against the remote source. The two installer calls share one
runner detection and fail independently.
Installs the bundled clerk-cli skill standalone so projects set up before
the skill was bundled, or CLIs upgraded since, can pull it in without
re-running init. `init` now delegates the clerk-cli portion to shared
core in commands/skill/install.ts, keeping a single runner detection
across clerk-cli and upstream framework skills.
Also extracts PACKAGE_MANAGERS as the canonical tuple plus derived type
in lib/package-manager.ts, reused by both `init --pm` and
`skill install --pm` choices. PM_PRIORITY in bootstrap keeps its
semantic name via `satisfies readonly PackageManager[]` plus a
compile-time exhaustiveness guard.
Fix the nano-staged oxlint hook to pass `-c .oxlintrc.json` explicitly
so override files (e.g. `unicorn/no-process-exit` off in cli-program.ts)
apply when linting specific paths; bare `oxlint <file>` does not
auto-discover the config.
Hoists the dev-version sentinel to a shared lib/version module so
cli-program.ts and install.ts stay in lockstep. Adds resolveCliVersion()
which maps both undefined and the 0.0.0-dev sentinel to undefined, letting
downstream callers treat unversioned binaries uniformly.
Threads the resolved version through withStagedClerkCliSkill so every
bundled asset has {{CLI_VERSION}} substituted at install time. The install
caller uses resolveCliVersion() instead of an inline typeof guard.
Import DEV_CLI_VERSION from packages/cli-core/src/lib/version.ts in
scripts/build.ts so the build script's default version arg stays in
lockstep with the sentinel used by the skill installer. Also extend
scripts/tsconfig.json to include globals.d.ts so CLI_VERSION is in
scope when tsc follows the cross-package import.
Remove the PackageManager type re-export from bootstrap-registry and
update consumers (bootstrap.ts, context.ts, index.ts) to import the
type directly from lib/package-manager.ts.
Adds init, apps create, open, completion, and skill install to the
Core commands table; adds --destructive to config patch/put; clarifies
config put semantics. Strengthens the Prerequisites section to make
'clerk doctor --json' the mandatory session-start check, with a note
to rerun 'clerk skill install' after upgrading the CLI so the bundled
skill matches the new binary.
Adds agent-mode behavior rows for 'apps create' (requires explicit
--json) and 'clerk open' (emits a JSON descriptor instead of launching
a browser), plus matching entries in the structured-outputs table.
Calls out 'clerk <command> --help' as the source of truth for flags so
the skill stays a hint rather than a spec, reducing drift surface.
Hidden commands (deploy, switch-env) remain undocumented.
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.
The bundled clerk skill drifted from the CLI source in a few places.
This commit resyncs the command reference and agent-mode docs:
- `clerk init`: document `--app` (skips interactive picker)
- `clerk config patch`/`put`: document `--app` and `--instance`
- Add `clerk update` row to the core commands table
- `references/agent-mode.md`: document the structured JSON error
output (`{"error":{...}}` on stderr) that agent mode emits, split
error-format guidance into human vs agent columns
- SKILL.md: expand the `clerk doctor --json` shape to include
`detail` and `fix` alongside `remedy`
Correct documentation drift identified by skill audit:
- OpenAPI catalog cache TTL is 1 hour, not 24 hours (matches
CACHE_TTL_MS in packages/cli-core/src/lib/constants.ts).
- `apps create` auto-emits JSON in agent mode via the shared
printJson() helper, same as `apps list`; update agent-mode matrix
and SKILL.md bullet so agents don't unnecessarily add --json.
Pull the accurate, CLI-verified additions from the external clerk-cli skill
draft into the bundled clerk skill:
- Document auth aliases: signup/signin/sign-in, signout/sign-out, and the
top-level clerk login / clerk logout shortcuts.
- Explain --destructive on config patch (same semantics as on config put).
- Note that config commands authenticate via the Platform API and do not
accept --secret-key.
- Add a mapping from each failing clerk doctor check to the manual
remediation command (auth login / link / env pull), since doctor --fix
is disabled in agent mode.
PR #29 items skipped because they drift from the current CLI source:
the {checks, overall} doctor JSON wrapper (actual output is a flat array)
and doctor --fix working in agent mode (source gates it on isHuman()).
Co-authored-by: Rafael Thayto <rafa.thayto@gmail.com>
Replace hardcoded ~/.clerk/config.json and ~/.clerk/cache/ paths with
platform-agnostic guidance since constants.ts uses envPaths (XDG). Add
CLERK_CONFIG_DIR to the environment variables table.
- Remove "clerk" from BASE_SKILLS so the upstream clerk/skills install
no longer overwrites the bundled pinned skill
- Import DEV_CLI_VERSION in update-check.ts to eliminate duplicate sentinel
- Move detectPackageManager to lib/package-manager; re-export from context
- Expand version substitution tests to cover all 4 bundled skill files
@wyattjoh
wyattjohforce-pushed the feat/clerk-cli-skill-pinned branch from a1a52fd to 6d0ef8aCompareApril 20, 2026 15:00
@wyattjoh
wyattjoh merged commit 8c02278 into mainApr 20, 2026
10 checks passed
@wyattjoh
wyattjoh deleted the feat/clerk-cli-skill-pinned branch April 20, 2026 17:54
@github-actionsgithub-actionsBot mentioned this pull request Apr 20, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@wyattjoh@rafa-thayto