diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f74ab4..d648965 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,12 @@ 本项目遵循 [语义化版本](https://semver.org/lang/zh-CN/)。 +## [1.0.2] - 2026-08-06 + +### 变更 + +- `install` 默认直接覆盖已安装的 Skill,无需再加 `--force`(旧的 `--force` 仍可兼容传入) + ## [1.0.1] - 2026-08-06 ### 新增 diff --git a/CHANGELOG_EN.md b/CHANGELOG_EN.md index 42eed10..ed7799a 100644 --- a/CHANGELOG_EN.md +++ b/CHANGELOG_EN.md @@ -4,6 +4,12 @@ This project follows [Semantic Versioning](https://semver.org/). +## [1.0.2] - 2026-08-06 + +### Changed + +- `install` overwrites an existing skill by default; `--force` is no longer required (still accepted for compatibility) + ## [1.0.1] - 2026-08-06 ### Added diff --git a/README.md b/README.md index 49b6bdf..28853ed 100644 --- a/README.md +++ b/README.md @@ -58,16 +58,16 @@ npx open-kimi-ppt-skills install --target ~/.workbuddy/skills ### 更新 -Skill 有更新时,用 `--force` 覆盖本地已安装版本即可(不要重复执行无 `--force` 的 install): +Skill 有更新时,再执行一次安装即可(会直接覆盖本地已安装版本): ```bash -npx open-kimi-ppt-skills@latest install --force +npx open-kimi-ppt-skills@latest install ``` 若当初用过 `--target`,更新时带上相同路径: ```bash -npx open-kimi-ppt-skills@latest install --force --target ~/.claude/skills +npx open-kimi-ppt-skills@latest install --target ~/.claude/skills ``` 也可以对 AI 说:`帮我更新 open-kimi-ppt skill`。更新只替换 Skill 文件,不会影响已生成的 PPTD / PPTX 项目。 diff --git a/README_EN.md b/README_EN.md index 2513081..47f10c3 100644 --- a/README_EN.md +++ b/README_EN.md @@ -58,16 +58,16 @@ npx open-kimi-ppt-skills install --target ~/.workbuddy/skills ### Update -When the skill is updated, overwrite the local install with `--force` (do not keep re-running install without `--force`): +When the skill is updated, run install again — it overwrites the local installation: ```bash -npx open-kimi-ppt-skills@latest install --force +npx open-kimi-ppt-skills@latest install ``` If you originally installed with `--target`, pass the same path again: ```bash -npx open-kimi-ppt-skills@latest install --force --target ~/.claude/skills +npx open-kimi-ppt-skills@latest install --target ~/.claude/skills ``` You can also ask your agent: `Update the open-kimi-ppt skill for me.` Updating only replaces the skill files; it does not touch PPTD / PPTX projects you already generated. diff --git a/bin/open-kimi-ppt-skills.js b/bin/open-kimi-ppt-skills.js index 27f2d04..83e6627 100755 --- a/bin/open-kimi-ppt-skills.js +++ b/bin/open-kimi-ppt-skills.js @@ -44,8 +44,8 @@ Usage: Install options: --target Skills directory (default: ~/.agents/skills) - --force Replace an existing installation +Re-running install replaces an existing open-kimi-ppt installation. Run "open-kimi-ppt-skills serve --help" for server options. `); } @@ -55,13 +55,13 @@ function parseArguments(arguments_) { const command = args[0] === "install" || args[0] === "serve" ? args.shift() : "install"; const options = command === "serve" ? { command, open: false, port: 55173 } - : { command, force: false, target: undefined }; + : { command, target: undefined }; while (args.length > 0) { const argument = args.shift(); + // Accepted for backward compatibility; install always overwrites. if (command === "install" && argument === "--force") { - options.force = true; continue; } @@ -111,19 +111,14 @@ function defaultSkillsDirectory() { return join(homedir(), ".agents", "skills"); } -function installSkill({ force, target }) { +function installSkill({ target }) { if (!existsSync(join(sourceDirectory, "SKILL.md"))) { throw new Error(`packaged skill is incomplete: ${sourceDirectory}`); } const skillsDirectory = target ?? defaultSkillsDirectory(); const destination = join(skillsDirectory, SKILL_NAME); - - if (existsSync(destination) && !force) { - throw new Error( - `${destination} already exists; rerun with --force to replace it`, - ); - } + const replaced = existsSync(destination); mkdirSync(skillsDirectory, { recursive: true }); const stagingRoot = mkdtempSync(join(skillsDirectory, `.${SKILL_NAME}-`)); @@ -135,16 +130,17 @@ function installSkill({ force, target }) { filter: (source) => ![".DS_Store", "_user_meta.json"].includes(basename(source)), }); - if (force) { - rmSync(destination, { recursive: true, force: true }); - } - + rmSync(destination, { recursive: true, force: true }); renameSync(stagedSkill, destination); } finally { rmSync(stagingRoot, { recursive: true, force: true }); } - console.log(`Installed ${SKILL_NAME} to ${destination}`); + console.log( + replaced + ? `Updated ${SKILL_NAME} at ${destination}` + : `Installed ${SKILL_NAME} to ${destination}`, + ); } async function main() { diff --git a/package.json b/package.json index 7d317b9..d8afd3d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "open-kimi-ppt-skills", - "version": "1.0.1", + "version": "1.0.2", "description": "Unofficial reverse-engineered Kimi Slides skill for AI coding agents with local PPTD editing and PPTX export.", "license": "MIT", "author": "binaryify", diff --git a/test/install-skill.test.js b/test/install-skill.test.js index 1e5614c..f38dca7 100644 --- a/test/install-skill.test.js +++ b/test/install-skill.test.js @@ -43,21 +43,7 @@ test("installs into ~/.agents/skills when no target is provided", () => { } }); -test("refuses to overwrite an existing installation without --force", () => { - const root = mkdtempSync(join(tmpdir(), "open-kimi-ppt-test-")); - const target = join(root, "skills"); - - try { - assert.equal(runCli(["--target", target]).status, 0); - const secondInstall = runCli(["--target", target]); - assert.equal(secondInstall.status, 1); - assert.match(secondInstall.stderr, /already exists/); - } finally { - rmSync(root, { recursive: true, force: true }); - } -}); - -test("replaces an existing installation with --force", () => { +test("overwrites an existing installation by default", () => { const root = mkdtempSync(join(tmpdir(), "open-kimi-ppt-test-")); const target = join(root, "skills"); const skillFile = join(target, "open-kimi-ppt", "SKILL.md"); @@ -66,10 +52,25 @@ test("replaces an existing installation with --force", () => { assert.equal(runCli(["--target", target]).status, 0); writeFileSync(skillFile, "modified", "utf8"); - const result = runCli(["--target", target, "--force"]); + const result = runCli(["--target", target]); assert.equal(result.status, 0, result.stderr); + assert.match(result.stdout, /Updated open-kimi-ppt/); assert.match(readFileSync(skillFile, "utf8"), /^---\nname: open-kimi-ppt/m); } finally { rmSync(root, { recursive: true, force: true }); } }); + +test("accepts legacy --force without changing overwrite behavior", () => { + const root = mkdtempSync(join(tmpdir(), "open-kimi-ppt-test-")); + const target = join(root, "skills"); + + try { + assert.equal(runCli(["--target", target]).status, 0); + const result = runCli(["--target", target, "--force"]); + assert.equal(result.status, 0, result.stderr); + assert.match(result.stdout, /Updated open-kimi-ppt/); + } finally { + rmSync(root, { recursive: true, force: true }); + } +});