OpenSpec 在 CI 中报 "Legacy files detected in non-interactive mode" 怎么解决?
【免费下载链接】OpenSpecSpec-driven development (SDD) for AI coding assistants.项目地址: https://gitcode.com/GitHub_Trending/op/OpenSpec
在 CI 流水线或任何非交互 shell 里跑openspec init时,如果项目里残留着旧版 OpenSpec 生成的文件(旧的斜杠命令目录、带 OpenSpec 标记块的工具配置文件等),init 检测到这些遗留文件后本应弹出确认提示Legacy files detected. Upgrade and clean up? [Y/n]。但 CI 里没有任何进程能回答这个问题,init 会以退出码 1 中止并列出它检测到的遗留文件,报出"Legacy files detected in non-interactive mode"。
解决办法很直接:用--force标志跳过提示、自动批准清理。适用前提是:CI/非交互环境(没有终端可以应答提示的 shell、AI agent 调用、stdin 已关闭的场景),且你确认项目里这些遗留文件属于旧版 OpenSpec 产物、可以被清理。
为什么 CI 里会失败:这个报错的机制
报错不是 bug,而是保护机制。OpenSpec 在init时按顺序检测三类遗留物:
- 带 OpenSpec 标记块(
<!-- OPENSPEC:START -->到<!-- OPENSPEC:END -->)的工具配置文件,如CLAUDE.md、.cursorrules、.windsurfrules、.clinerules、.github/copilot-instructions.md、CODEBUDDY.md、IFLOW.md等; - 旧的斜杠命令目录,如
.claude/commands/openspec/、.windsurf/workflows/openspec-*.md; - 旧的 OpenSpec 结构文件,如
openspec/AGENTS.md、带 OpenSpec 标记的根AGENTS.md。
检测到遗留物后,交互式运行会先展示"找到了什么",再请求确认;用户按 N 则中止初始化并建议使用--force手动处理。而在 CI 环境中(--no-interactive或无法应答提示),检测到遗留物就直接以退出码 1 中止、打印检测清单并建议改用交互模式或--force运行。也就是说,这条报错本身就是在告诉你下一步该做什么。
解决方法:openspec init --force
docs/troubleshooting.md 和 docs/migration-guide.md 给出的修复命令一致:
openspec init --forceCLI 参考对--force的定义是 "Auto-cleanup legacy files without prompting"——自动清理遗留文件、不弹提示。清理会执行但不做外科手术式的误删,规则如下:
- 只含 OpenSpec 标记块(标记外允许空白)的配置文件:移除标记块,但保留文件本身,不删除文件;
- 标记块内外都有内容的配置文件(包括根
AGENTS.md):只移除标记块,保留标记前后的内容,并清理产生的多余空行; - 遗留斜杠命令目录(如
.claude/commands/openspec/):整个目录删除,父目录(如.claude/commands/)保留; openspec/AGENTS.md:删除该文件,不删除openspec/目录本身。
一个需要注意的例外:openspec/project.md永远不会被自动删除,因为里面可能有你手写的内容。清理完成后如果它还存在,输出中会出现这样一段迁移提示(文档示例):
Manual migration needed: → openspec/project.md still exists Move useful content to config.yaml's "context:" field, then delete处理方式是把有用内容移入openspec/config.yaml的context:字段,然后手动删除该文件。迁移指南提供了完整步骤。
在 CI 中完整跑通非交互初始化
--force只解决遗留清理的确认提示。如果 CI 里还要指定要为哪些 AI 工具生成 skills/commands,用--tools一起传入,避免其他交互提问:
openspec init --force --tools claude,cursordocs/cli.md 中的非交互示例形式为openspec init --tools claude,cursor;--tools支持all、none或逗号分隔的工具 ID 列表,完整 ID 列表见 Supported Tools。如果你只关心清理和生成openspec/目录结构、不配置任何工具,用--tools none。
清理后如何验证
重新运行原命令:
openspec init --force应以退出码 0 正常结束,不再打印"Legacy files detected in non-interactive mode"的检测清单。查看清理摘要:清理完成时输出会带一段
Cleaned up legacy files:摘要(文档示例):Cleaned up legacy files: ✓ Removed OpenSpec markers from CLAUDE.md ✓ Removed .claude/commands/openspec/ (replaced by OpenSpec skills and commands) ✓ Removed openspec/AGENTS.md (no longer needed)没有检测到遗留物时不会出现这段摘要,直接进入 skill 配置。
检查文件状态:
openspec/AGENTS.md应已不存在而openspec/目录仍在;.claude/commands/openspec/目录应已不存在而.claude/commands/仍在;CLAUDE.md等配置文件仍在,只是 OpenSpec 标记块被移除、你自己的内容保留。确认命令生效:如果之后发现工具里
/opsx:*命令没出现,重启 IDE(skills 在启动时检测),仍不出现则跑openspec update并核对 Supported Tools 里的文件位置。
边界与限制
- Codex 的旧提示文件有特殊限制:OpenSpec 可能检测到
$CODEX_HOME/prompts或~/.codex/prompts下的旧版受管提示文件,但清理范围限于 OpenSpec 允许名单内的遗留 Codex 提示文件名,并且非交互init只删除其对应的.agents/skills/openspec-*skill 已存在的那些文件。 openspec update的行为不同:非交互的openspec update即使发现遗留文件也只警告、不中止;要让它执行清理必须显式传--force。另外注意update的--force含义是 "Force update even when files are up to date",与init的--force(自动清理遗留文件)不是同一个作用,别混用。- 交互式环境下想先看看会清理什么:本地运行时直接跑
openspec init然后在清理提示处拒绝(按 N)——init 会打印完整的检测结果但不做任何更改,之后确认无误再走--force。
如果--force之后流水线仍失败,按 troubleshooting 文档 的建议:记录 OpenSpec 版本(openspec --version)、Node 版本(node --version,要求 20.19.0 及以上)、使用的 AI 工具,以及原始命令和完整输出,再通过openspec feedback提交 issue 求助。
【免费下载链接】OpenSpecSpec-driven development (SDD) for AI coding assistants.项目地址: https://gitcode.com/GitHub_Trending/op/OpenSpec
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考