From bd97809062aa59c3128b19999b7dbb004b1619fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=86=AF=E5=9F=BA=E9=AD=81?= <1412414664@qq.com> Date: Mon, 6 Jul 2026 20:55:21 +0800 Subject: [PATCH] fix: match archived changes by exact slug --- assets/skills/_shared/references/openspec.js | 11 ++++++++++- test/reference-scripts.test.ts | 20 ++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/assets/skills/_shared/references/openspec.js b/assets/skills/_shared/references/openspec.js index 5e287fe..b785487 100644 --- a/assets/skills/_shared/references/openspec.js +++ b/assets/skills/_shared/references/openspec.js @@ -581,6 +581,15 @@ async function resolveArchivedChangeLocation(projectDir, slug) { return null } + const matchesArchivedSlug = (entryName) => { + if (entryName === slug) { + return true + } + + const datedMatch = entryName.match(/^\d{4}-\d{2}-\d{2}-(.+)$/) + return datedMatch?.[1] === slug + } + const entries = await readdir(archivedRoot, { withFileTypes: true }) for (const entry of entries) { if (!entry.isDirectory()) { @@ -588,7 +597,7 @@ async function resolveArchivedChangeLocation(projectDir, slug) { } const dirPath = path.join(archivedRoot, entry.name) - if (entry.name === slug || entry.name.endsWith(`-${slug}`)) { + if (matchesArchivedSlug(entry.name)) { return { dirPath, slug, diff --git a/test/reference-scripts.test.ts b/test/reference-scripts.test.ts index 86d7297..f6b1133 100644 --- a/test/reference-scripts.test.ts +++ b/test/reference-scripts.test.ts @@ -6,6 +6,8 @@ import { promisify } from "node:util" import { afterEach, beforeEach, describe, expect, it } from "vitest" +import { resolveChangeLocation } from "../assets/skills/_shared/references/openspec.js" + const execFileAsync = promisify(execFile) const tempDirs: string[] = [] @@ -130,4 +132,22 @@ describe("reference scripts", () => { expect(archived.specsMergedTo).toEqual(["openspec/specs/archive-change/spec.md"]) expect(await exists(path.join(projectDir, "openspec", "specs", "archive-change", "spec.md"))).toBe(true) }) + + it("archived change lookup does not match suffix-only slugs", async () => { + const projectDir = await createWorkspace() + const archiveDir = path.join(projectDir, "openspec", "changes", "archive", "2026-01-01-add-user-auth") + await mkdir(archiveDir, { recursive: true }) + await writeFile( + path.join(archiveDir, "proposal.md"), + '---\nslug: "add-user-auth"\ncreatedAt: "2026-01-01T00:00:00.000Z"\n---\n\n# Proposal\n', + "utf8", + ) + + await expect(resolveChangeLocation(projectDir, "add-user-auth")).resolves.toMatchObject({ + dirPath: archiveDir, + slug: "add-user-auth", + status: "archived", + }) + await expect(resolveChangeLocation(projectDir, "user-auth")).resolves.toBeNull() + }) })