chore: release 1.0.0

This commit is contained in:
xixu-me committed 2026-03-27 10:51:14 +08:00
1 parent b80f31616a
commit d48830353d
18 files changed
+107 -118

No files matched your search

+1 -1
View File
@@ -28,7 +28,7 @@ concurrency:
env:
# npm trusted publishing requires Node 22.14.0+ and npm 11.5.1+.
NODE_VERSION: "24"
PACKAGE_NAME: "@xixu-me/skills-vault"
PACKAGE_NAME: "skvlt"
NPM_DIST_TAG: ${{ github.event_name == 'workflow_dispatch' && inputs.npm_dist_tag || 'latest' }}
jobs:
+20 -28
View File
@@ -2,7 +2,7 @@
**_[汉语](./README.zh.md)_**
[![npm version](https://img.shields.io/npm/v/%40xixu-me%2Fskills-vault)](https://www.npmjs.com/package/@xixu-me/skills-vault)
[![npm version](https://img.shields.io/npm/v/skvlt)](https://www.npmjs.com/package/skvlt)
[![CI](https://img.shields.io/github/actions/workflow/status/xixu-me/skills-vault/ci.yml?branch=main&label=ci)](https://github.com/xixu-me/skills-vault/actions/workflows/ci.yml)
[![Bun](https://img.shields.io/badge/Bun-%3E%3D1.3.11-f9f1e1)](https://bun.sh/)
[![License](https://img.shields.io/badge/license-MIT-blue)](./LICENSE)
@@ -28,32 +28,24 @@ Skills Vault exists to fill the gap described in [vercel-labs/skills#729](https:
- Check local setup quickly with `doctor`.
- Generate completion scripts for `bash`, `zsh`, and `powershell`.
## Install
Install the CLI globally with Bun:
```bash
bun add -g @xixu-me/skills-vault
```
## Quick Start
Back up your current skills:
```bash
skvlt backup
bunx skvlt backup
```
Preview what a restore would run:
```bash
skvlt restore --dry-run
bunx skvlt restore --dry-run
```
Restore everything recorded in the manifest:
```bash
skvlt restore --all
bunx skvlt restore --all
```
If you want a curated, ready-to-use manifest, see [xixu-me/skvlt](https://github.com/xixu-me/skvlt), a maintained collection of `skvlt.yaml` snapshots.
@@ -85,10 +77,10 @@ sources:
Snapshot installed skills into `skvlt.yaml`.
```bash
skvlt backup
skvlt backup --dry-run
skvlt backup --output ./skvlt.yaml
skvlt backup --project-scope --lock-file ./skills-lock.json
bunx skvlt backup
bunx skvlt backup --dry-run
bunx skvlt backup --output ./skvlt.yaml
bunx skvlt backup --project-scope --lock-file ./skills-lock.json
```
`backup` reads installed skill names, joins them with lock-file metadata, and writes a grouped manifest keyed by source.
@@ -101,10 +93,10 @@ skvlt backup --project-scope --lock-file ./skills-lock.json
Install skills from a manifest.
```bash
skvlt restore --all
skvlt restore --only-source xixu-me/skills
skvlt restore --project-scope
skvlt restore --dry-run
bunx skvlt restore --all
bunx skvlt restore --only-source xixu-me/skills
bunx skvlt restore --project-scope
bunx skvlt restore --dry-run
```
By default, restore respects the scope recorded in the manifest. Use `--project-scope` to force a project install even when the manifest was created from global state.
@@ -118,8 +110,8 @@ For a curated manifest source, you can start from [xixu-me/skvlt](https://github
Inspect the local Skills Vault environment and global skill state.
```bash
skvlt doctor
skvlt doctor --manifest ./skvlt.yaml
bunx skvlt doctor
bunx skvlt doctor --manifest ./skvlt.yaml
```
`doctor` checks:
@@ -135,9 +127,9 @@ skvlt doctor --manifest ./skvlt.yaml
Print shell completion scripts.
```bash
skvlt completion bash
skvlt completion zsh
skvlt completion powershell
bunx skvlt completion bash
bunx skvlt completion zsh
bunx skvlt completion powershell
```
## JSON Output
@@ -145,8 +137,8 @@ skvlt completion powershell
All top-level commands support `--json` for structured output:
```bash
skvlt --json doctor
skvlt --json backup --dry-run
bunx skvlt --json doctor
bunx skvlt --json backup --dry-run
```
Successful responses include `ok`, `command`, and `data`. Failures include `ok`, `command`, and a stable `error.code` plus message.
@@ -197,7 +189,7 @@ npm publish --access public
## Troubleshooting
- If restore reports a global state mismatch, inspect `~/.agents/.skill-lock.json` and `~/.agents/skills`.
- If environment checks fail, start with `skvlt doctor`.
- If environment checks fail, start with `bunx skvlt doctor`.
- If packaging checks fail, run `bun run check` and review the tarball output from `npm pack --dry-run --json`.
For contribution, support, and security policy details, see [`CONTRIBUTING.md`](./CONTRIBUTING.md), [`SUPPORT.md`](./SUPPORT.md), and [`SECURITY.md`](./SECURITY.md).
+20 -28
View File
@@ -2,7 +2,7 @@
**_[English](./README.md)_**
[![npm version](https://img.shields.io/npm/v/%40xixu-me%2Fskills-vault)](https://www.npmjs.com/package/@xixu-me/skills-vault)
[![npm version](https://img.shields.io/npm/v/skvlt)](https://www.npmjs.com/package/skvlt)
[![CI](https://img.shields.io/github/actions/workflow/status/xixu-me/skills-vault/ci.yml?branch=main&label=ci)](https://github.com/xixu-me/skills-vault/actions/workflows/ci.yml)
[![Bun](https://img.shields.io/badge/Bun-%3E%3D1.3.11-f9f1e1)](https://bun.sh/)
[![License](https://img.shields.io/badge/license-MIT-blue)](./LICENSE)
@@ -28,32 +28,24 @@ Skills Vault 的存在,是为了补上 [vercel-labs/skills#729](https://github
- 用 `doctor` 快速检查本地环境
- 为 `bash`、`zsh` 和 `powershell` 生成补全脚本
## 安装
使用 Bun 全局安装 CLI:
```bash
bun add -g @xixu-me/skills-vault
```
## 快速开始
备份当前已安装的 skills:
```bash
skvlt backup
bunx skvlt backup
```
预览一次 restore 将会执行什么:
```bash
skvlt restore --dry-run
bunx skvlt restore --dry-run
```
恢复 manifest 中记录的全部内容:
```bash
skvlt restore --all
bunx skvlt restore --all
```
如果你想直接使用一个精选好的 manifest,可以查看 [xixu-me/skvlt](https://github.com/xixu-me/skvlt),这是一个持续维护的 `skvlt.yaml` 集合。
@@ -85,10 +77,10 @@ sources:
把已安装的 skills 快照到 `skvlt.yaml`。
```bash
skvlt backup
skvlt backup --dry-run
skvlt backup --output ./skvlt.yaml
skvlt backup --project-scope --lock-file ./skills-lock.json
bunx skvlt backup
bunx skvlt backup --dry-run
bunx skvlt backup --output ./skvlt.yaml
bunx skvlt backup --project-scope --lock-file ./skills-lock.json
```
`backup` 会先读取已安装的 skill 名称,再结合 lock file 元数据,最终按 source 分组写出 manifest。
@@ -101,10 +93,10 @@ skvlt backup --project-scope --lock-file ./skills-lock.json
从 manifest 安装 skills。
```bash
skvlt restore --all
skvlt restore --only-source xixu-me/skills
skvlt restore --project-scope
skvlt restore --dry-run
bunx skvlt restore --all
bunx skvlt restore --only-source xixu-me/skills
bunx skvlt restore --project-scope
bunx skvlt restore --dry-run
```
默认情况下,`restore` 会遵循 manifest 中记录的 scope。如果希望即使 manifest 来自全局状态,也强制恢复到项目作用域,可以使用 `--project-scope`。
@@ -118,8 +110,8 @@ skvlt restore --dry-run
检查本地 Skills Vault 环境和全局 skill 状态。
```bash
skvlt doctor
skvlt doctor --manifest ./skvlt.yaml
bunx skvlt doctor
bunx skvlt doctor --manifest ./skvlt.yaml
```
`doctor` 会检查:
@@ -135,9 +127,9 @@ skvlt doctor --manifest ./skvlt.yaml
输出 shell 补全脚本。
```bash
skvlt completion bash
skvlt completion zsh
skvlt completion powershell
bunx skvlt completion bash
bunx skvlt completion zsh
bunx skvlt completion powershell
```
## JSON 输出
@@ -145,8 +137,8 @@ skvlt completion powershell
所有顶层命令都支持 `--json` 结构化输出:
```bash
skvlt --json doctor
skvlt --json backup --dry-run
bunx skvlt --json doctor
bunx skvlt --json backup --dry-run
```
成功时会返回 `ok`、`command` 和 `data`。失败时会返回 `ok`、`command`,以及稳定的 `error.code` 和错误消息。
@@ -197,7 +189,7 @@ npm publish --access public
## 故障排查
- 如果 restore 报告全局状态不一致,请检查 `~/.agents/.skill-lock.json` 和 `~/.agents/skills`
- 如果环境检查失败,先运行 `skvlt doctor`
- 如果环境检查失败,先运行 `bunx skvlt doctor`
- 如果打包检查失败,运行 `bun run check`,并检查 `npm pack --dry-run --json` 的输出
关于贡献、支持和安全策略,请参阅 [`CONTRIBUTING.md`](./CONTRIBUTING.md)、[`SUPPORT.md`](./SUPPORT.md) 和 [`SECURITY.md`](./SECURITY.md)。
+1 -1
View File
@@ -4,7 +4,7 @@
Security fixes are handled on a best-effort basis for:
- the latest published npm release of `@xixu-me/skills-vault`
- the latest published npm release of `skvlt`
- the current `main` branch in this repository
Older versions may receive guidance, but they should not be assumed to receive patches.
+1 -1
View File
@@ -3,7 +3,7 @@
"configVersion": 1,
"workspaces": {
"": {
"name": "@xixu-me/skills-vault",
"name": "skvlt",
"devDependencies": {
"prettier": "^3.8.1",
},
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@xixu-me/skills-vault",
"version": "1.1.2",
"name": "skvlt",
"version": "1.0.0",
"description": "The CLI for backing up and restoring Agent Skills",
"author": "Xi Xu",
"bin": {
+11 -11
View File
@@ -34,7 +34,7 @@ function printHelp(): string {
"The CLI for backing up and restoring Agent Skills",
"",
helpHeading("Usage"),
" skvlt <command> [options]",
" bunx skvlt <command> [options]",
"",
helpHeading("Commands"),
" backup Backup installed skills into a manifest",
@@ -48,11 +48,11 @@ function printHelp(): string {
" -v, --version Print the installed package version",
"",
helpHeading("Examples"),
helpExample("skvlt backup --output ./skvlt.yaml"),
helpExample("skvlt completion bash"),
helpExample("skvlt doctor"),
helpExample("skvlt restore --all"),
helpExample("skvlt restore --only-source xixu-me/skills"),
helpExample("bunx skvlt backup --output ./skvlt.yaml"),
helpExample("bunx skvlt completion bash"),
helpExample("bunx skvlt doctor"),
helpExample("bunx skvlt restore --all"),
helpExample("bunx skvlt restore --only-source xixu-me/skills"),
helpFooter("https://github.com/xixu-me/skills-vault"),
].join("\n")}`;
}
@@ -65,10 +65,10 @@ function printLanding(): string {
return `\n${[
dimGray("The CLI for backing up and restoring Agent Skills"),
"",
landingCommand("skvlt backup", "Backup installed skills"),
landingCommand("skvlt restore", "Restore from skvlt.yaml"),
landingCommand("skvlt doctor", "Inspect local setup"),
landingCommand("skvlt completion", "Print shell completions"),
landingCommand("bunx skvlt backup", "Backup installed skills"),
landingCommand("bunx skvlt restore", "Restore from skvlt.yaml"),
landingCommand("bunx skvlt doctor", "Inspect local setup"),
landingCommand("bunx skvlt completion", "Print shell completions"),
"",
`${dimGray("Explore the open-source repo at")} ${textGray("https://github.com/xixu-me/skills-vault")}\n`,
].join("\n")}`;
@@ -177,7 +177,7 @@ export async function runCli(
exitCode: 1,
stdout: "",
stderr: page(
`Unknown command: ${command}\nRun ${bold("skvlt --help")} for usage.`,
`Unknown command: ${command}\nRun ${bold("bunx skvlt --help")} for usage.`,
),
errorCode: "UNKNOWN_COMMAND",
};
+6 -6
View File
@@ -48,7 +48,7 @@ function printHelp(): string {
"Backup installed skills into skvlt.yaml.",
"",
helpHeading("Usage"),
" skvlt backup [options]",
" bunx skvlt backup [options]",
"",
helpHeading("Options"),
" --output <path> Output path for skvlt.yaml",
@@ -63,10 +63,10 @@ function printHelp(): string {
" - Project scope currently requires --lock-file because the Skills CLI does not expose a discoverable project lock path here.",
"",
helpHeading("Examples"),
helpExample("skvlt backup"),
helpExample(`skvlt backup --output ${formatCliPath("./skvlt.yaml")}`),
helpExample("bunx skvlt backup"),
helpExample(`bunx skvlt backup --output ${formatCliPath("./skvlt.yaml")}`),
helpExample(
`skvlt backup --project-scope --lock-file ${formatCliPath("./skills-lock.json")}`,
`bunx skvlt backup --project-scope --lock-file ${formatCliPath("./skills-lock.json")}`,
),
helpFooter("https://github.com/xixu-me/skills-vault"),
].join("\n")}`;
@@ -108,8 +108,8 @@ function formatBackupError(message: string, errorCode: string): string {
if (errorCode === "INVALID_ARGUMENT") {
return commandErrorPage(
message,
"skvlt backup [options]",
`skvlt backup --output ${formatCliPath("./skvlt.yaml")}`,
"bunx skvlt backup [options]",
`bunx skvlt backup --output ${formatCliPath("./skvlt.yaml")}`,
);
}
+7 -7
View File
@@ -21,18 +21,18 @@ export type CompletionRunResult = {
function printHelp(): string {
return `\n${[
"Print shell completion scripts for skvlt.",
"Print shell completion scripts for bunx skvlt.",
"",
helpHeading("Usage"),
" skvlt completion <bash|zsh|powershell>",
" bunx skvlt completion <bash|zsh|powershell>",
"",
helpHeading("Options"),
" --help Show this help",
"",
helpHeading("Examples"),
helpExample("skvlt completion bash"),
helpExample("skvlt completion zsh"),
helpExample("skvlt completion powershell"),
helpExample("bunx skvlt completion bash"),
helpExample("bunx skvlt completion zsh"),
helpExample("bunx skvlt completion powershell"),
helpFooter("https://github.com/xixu-me/skills-vault"),
].join("\n")}`;
}
@@ -154,8 +154,8 @@ function formatCompletionError(message: string, errorCode: string): string {
if (errorCode === "INVALID_ARGUMENT") {
return commandErrorPage(
message,
"skvlt completion <bash|zsh|powershell>",
"skvlt completion bash",
"bunx skvlt completion <bash|zsh|powershell>",
"bunx skvlt completion bash",
);
}
+5 -5
View File
@@ -59,15 +59,15 @@ function printHelp(): string {
"Inspect the local Skills Vault environment and installation state.",
"",
helpHeading("Usage"),
" skvlt doctor [options]",
" bunx skvlt doctor [options]",
"",
helpHeading("Options"),
" --manifest <path> Manifest path to inspect",
" --help Show this help",
"",
helpHeading("Examples"),
helpExample("skvlt doctor"),
helpExample("skvlt doctor --manifest ./skvlt.yaml"),
helpExample("bunx skvlt doctor"),
helpExample("bunx skvlt doctor --manifest ./skvlt.yaml"),
helpFooter("https://github.com/xixu-me/skills-vault"),
].join("\n")}`;
}
@@ -110,8 +110,8 @@ function formatDoctorError(message: string): string {
) {
return commandErrorPage(
message,
"skvlt doctor [options]",
"skvlt doctor --manifest ./skvlt.yaml",
"bunx skvlt doctor [options]",
"bunx skvlt doctor --manifest ./skvlt.yaml",
);
}
+6 -6
View File
@@ -77,7 +77,7 @@ function printHelp(): string {
"Restore skills from skvlt.yaml.",
"",
helpHeading("Usage"),
" skvlt restore [options]",
" bunx skvlt restore [options]",
"",
helpHeading("Options"),
" --manifest <path> Path to skvlt.yaml",
@@ -98,9 +98,9 @@ function printHelp(): string {
` - Global restore verifies ${formatCliPath(defaultGlobalSkillsPath)} against ${formatCliPath(defaultGlobalLockFilePath)}`,
"",
helpHeading("Examples"),
helpExample("skvlt restore --only-source xixu-me/skills"),
helpExample("skvlt restore --all"),
helpExample("skvlt restore --project-scope --manifest ./skvlt.yaml"),
helpExample("bunx skvlt restore --only-source xixu-me/skills"),
helpExample("bunx skvlt restore --all"),
helpExample("bunx skvlt restore --project-scope --manifest ./skvlt.yaml"),
helpFooter("https://github.com/xixu-me/skills-vault"),
].join("\n")}`;
}
@@ -143,8 +143,8 @@ function formatRestoreError(message: string, errorCode: string): string {
if (errorCode === "INVALID_ARGUMENT") {
return commandErrorPage(
message,
"skvlt restore [options]",
"skvlt restore --all",
"bunx skvlt restore [options]",
"bunx skvlt restore --all",
);
}
+4 -2
View File
@@ -57,7 +57,7 @@ export function buildManifest(
lines.push("");
lines.push("sources:");
for (const source of sortedSources) {
for (const [index, source] of sortedSources.entries()) {
const skills = [...(groups.get(source) ?? [])].sort((left, right) =>
left.localeCompare(right),
);
@@ -67,7 +67,9 @@ export function buildManifest(
for (const skill of skills) {
lines.push(` - ${encodeDoubleQuotedYamlScalar(skill)}`);
}
lines.push("");
if (index < sortedSources.length - 1) {
lines.push("");
}
}
return {
+5 -6
View File
@@ -26,9 +26,9 @@ test("renders backup argument errors as a usage page", async () => {
expect(plainStderr).toContain("ERROR");
expect(plainStderr).toContain("--output requires a path");
expect(plainStderr).toContain("Usage:");
expect(plainStderr).toContain("skvlt backup [options]");
expect(plainStderr).toContain("bunx skvlt backup [options]");
expect(plainStderr).toContain("Example:");
expect(plainStderr).toContain("skvlt backup --output");
expect(plainStderr).toContain("bunx skvlt backup --output");
expect(plainStderr.endsWith("\n\n")).toBe(true);
});
@@ -117,7 +117,6 @@ test("prints deterministic manifest YAML during backup dry-run", async () => {
" skills:",
' - "alpha"',
' - "zulu"',
"",
].join("\n") + "\n",
);
});
@@ -212,7 +211,7 @@ test("shows help before project-scope validation", async () => {
expect(result.stdout).toContain("\x1b[1mUsage:\x1b[0m");
expect(result.stdout).toContain("\x1b[1mExamples:\x1b[0m");
expect(result.stdout).toContain("\x1b[38;5;102m$\x1b[0m");
expect(result.stdout).not.toContain("skvlt backup --dry-run");
expect(result.stdout).not.toContain("bunx skvlt backup --dry-run");
expect(plainStdout).toContain(
"\n\nExplore the open-source repo at https://github.com/xixu-me/skills-vault",
);
@@ -268,6 +267,7 @@ test("builds a grouped manifest with stable source and skill ordering", () => {
expect(manifest.totalSources).toBe(2);
expect(manifest.totalSkills).toBe(3);
expect(manifest.yaml.endsWith("\n\n")).toBe(false);
expect(manifest.yaml).toBe(
[
"# Generated by Skills Vault: https://github.com/xixu-me/skills-vault",
@@ -286,7 +286,6 @@ test("builds a grouped manifest with stable source and skill ordering", () => {
" skills:",
' - "alpha"',
' - "zulu"',
"",
].join("\n") + "\n",
);
});
@@ -299,6 +298,7 @@ test("builds double-quoted yaml scalars with escaped special characters", () =>
},
});
expect(manifest.yaml.endsWith("\n\n")).toBe(false);
expect(manifest.yaml).toBe(
[
"# Generated by Skills Vault: https://github.com/xixu-me/skills-vault",
@@ -316,7 +316,6 @@ test("builds double-quoted yaml scalars with escaped special characters", () =>
" count: 1",
" skills:",
' - "path\\\\skill"',
"",
].join("\n") + "\n",
);
});
+8 -6
View File
@@ -67,14 +67,16 @@ test("prints top-level help", async () => {
"The CLI for backing up and restoring Agent Skills",
);
expect(result.stdout).toContain("Usage:");
expect(result.stdout).toContain("skvlt <command> [options]");
expect(result.stdout).toContain("bunx skvlt <command> [options]");
expect(result.stdout).toContain("backup");
expect(result.stdout).toContain("completion");
expect(result.stdout).toContain("doctor");
expect(result.stdout).toContain("restore");
expect(result.stdout).toContain("skvlt restore --only-source xixu-me/skills");
expect(result.stdout).not.toContain("skvlt backup --dry-run");
expect(result.stdout).not.toContain("skvlt restore --dry-run");
expect(result.stdout).toContain(
"bunx skvlt restore --only-source xixu-me/skills",
);
expect(result.stdout).not.toContain("bunx skvlt backup --dry-run");
expect(result.stdout).not.toContain("bunx skvlt restore --dry-run");
expect(result.stdout).not.toContain("anthropics/skills");
expect(result.stdout).toContain("\x1b[1mUsage:\x1b[0m");
expect(result.stdout).toContain("\x1b[1mExamples:\x1b[0m");
@@ -126,10 +128,10 @@ test("rejects unknown commands with guidance", async () => {
expect(result.stdout).toBe("");
expect(plainStderr.startsWith("\n")).toBe(true);
expect(plainStderr).toContain("Unknown command: sync");
expect(plainStderr).toContain("Run skvlt --help for usage.");
expect(plainStderr).toContain("Run bunx skvlt --help for usage.");
expect(plainStderr.endsWith("\n\n")).toBe(true);
expect(result.stderr).toContain("Unknown command: sync");
expect(result.stderr).toContain("\x1b[1mskvlt --help\x1b[0m");
expect(result.stderr).toContain("\x1b[1mbunx skvlt --help\x1b[0m");
});
test("returns JSON errors for unknown commands", async () => {
+3 -3
View File
@@ -12,7 +12,7 @@ test("shows completion help text", async () => {
expect(result.exitCode).toBe(0);
expect(plainStdout.startsWith("\n")).toBe(true);
expect(result.stdout).toContain("Usage:");
expect(result.stdout).toContain("skvlt completion");
expect(result.stdout).toContain("bunx skvlt completion");
expect(result.stdout).toContain("\x1b[1mUsage:\x1b[0m");
expect(plainStdout).toContain(
"\n\nExplore the open-source repo at https://github.com/xixu-me/skills-vault",
@@ -50,9 +50,9 @@ test("rejects unsupported shells with a stable error code", async () => {
expect(plainStderr).toContain("ERROR");
expect(plainStderr).toContain("Unsupported shell: fish");
expect(plainStderr).toContain("Usage:");
expect(plainStderr).toContain("skvlt completion <bash|zsh|powershell>");
expect(plainStderr).toContain("bunx skvlt completion <bash|zsh|powershell>");
expect(plainStderr).toContain("Example:");
expect(plainStderr).toContain("skvlt completion bash");
expect(plainStderr).toContain("bunx skvlt completion bash");
expect(plainStderr.endsWith("\n\n")).toBe(true);
expect(result.stderr).toContain("\x1b[");
expect(result.stderr).toContain("ERROR");
+1 -1
View File
@@ -13,7 +13,7 @@ test("shows doctor help text", async () => {
expect(result.exitCode).toBe(0);
expect(plainStdout.startsWith("\n")).toBe(true);
expect(result.stdout).toContain("Usage:");
expect(result.stdout).toContain("skvlt doctor");
expect(result.stdout).toContain("bunx skvlt doctor");
expect(result.stdout).toContain("\x1b[1mUsage:\x1b[0m");
expect(plainStdout).toContain(
"\n\nExplore the open-source repo at https://github.com/xixu-me/skills-vault",
+2
View File
@@ -14,10 +14,12 @@ test("uses package scripts that point at the skvlt cli entrypoint", () => {
) as {
bin?: Record<string, string>;
engines?: Record<string, string>;
name?: string;
publishConfig?: Record<string, string>;
scripts?: Record<string, string>;
};
expect(packageJson.name).toBe("skvlt");
expect(normalizeBinTarget(packageJson.bin?.skvlt)).toBe("src/cli.ts");
expect(packageJson.engines?.bun).toBe(">=1.3.11");
expect(packageJson.publishConfig?.access).toBe("public");
+4 -4
View File
@@ -30,8 +30,8 @@ test("shows restore help text", async () => {
expect(result.exitCode).toBe(0);
expect(plainStdout.startsWith("\n")).toBe(true);
expect(result.stdout).toContain("Usage:");
expect(result.stdout).toContain("skvlt restore");
expect(result.stdout).not.toContain("skvlt restore --dry-run");
expect(result.stdout).toContain("bunx skvlt restore");
expect(result.stdout).not.toContain("bunx skvlt restore --dry-run");
expect(plainStdout).toContain(
"\n\nExplore the open-source repo at https://github.com/xixu-me/skills-vault",
);
@@ -505,8 +505,8 @@ test("renders restore argument errors as a usage page", async () => {
expect(plainStderr).toContain("ERROR");
expect(plainStderr).toContain("--concurrency requires a value");
expect(plainStderr).toContain("Usage:");
expect(plainStderr).toContain("skvlt restore [options]");
expect(plainStderr).toContain("bunx skvlt restore [options]");
expect(plainStderr).toContain("Example:");
expect(plainStderr).toContain("skvlt restore --all");
expect(plainStderr).toContain("bunx skvlt restore --all");
expect(plainStderr.endsWith("\n\n")).toBe(true);
});