openspec-impact
v0.3.2
Published
Deterministic OpenSpec candidate-code-scope CLI
Downloads
574
Readme
openspec-impact
English
openspec-impact provides one CLI, installed as both osi and openspec-impact, for gathering deterministic evidence about a live OpenSpec change. It finds code files that match explicit citations in the change docs and adds limited Git history. It does not decide which files must change, and the CLI does not call an LLM.
An optional agent skill (/opsx-impact) reads the evidence and writes a human-readable impact report. For a product-manager-oriented overview, see the product guide.
Requirements
- Node.js 18 or later and Git.
rgis optional. Without it,osiwalks the project files and searches their contents directly.
Quick start
Install the latest release globally:
npm install -g openspec-impact@latestIn the project that contains the live OpenSpec change, install the impact skill for the agents you use:
cd your-openspec-project
osi initosi init checks the nearest OpenSpec project root for Cursor, Claude Code, Codex, Windsurf, Cline, Roo Code, OpenCode, GitHub Copilot, and Pi configuration. In a terminal it prints the paths it found, lists every supported agent, and marks the detected ones. Move with the up and down keys, toggle a row with space, and press enter to install. When nothing is detected, nothing is marked, and you can still choose. Only the agents you confirm are written; other agent files stay as they are.
In a script, pass the same ids and skip the prompt:
osi init --agent cursor,codexAgent ids: cursor, claude, codex, windsurf, cline, roo, opencode, github-copilot, pi. If stdin is not a terminal and --agent is missing, osi init exits with an error and writes nothing.
In the agent chat for that project, type the live change name:
/opsx-impact <change-name>For example, /opsx-impact add-renewal-status. Cursor, Claude Code, Windsurf, Cline, Roo Code, OpenCode, GitHub Copilot, and Pi use that slash command. Codex uses $opsx-impact <change-name>. The agent reads the evidence and replies with the impact report in the chat.
To get YAML evidence directly in a terminal, run:
osi impact add-renewal-statusAfter upgrading the global package, run osi init again, or pass --agent, to refresh the selected files:
npm install -g openspec-impact@latest
osi init --agent cursorIf osi or openspec-impact is not found after installation, add npm's global executable directory to your PATH. On Unix-like systems, this is the bin directory under npm prefix -g; on Windows, it is the directory returned by npm prefix -g.
Commands
osi and openspec-impact run the same commands. Examples below use osi.
osi impact [--no-search] [--include-low] <change-id|path>
osi scope [--no-search] [--include-low] <change-id|path>
osi history <change-id|path>
osi init [--agent <id[,id...]>]<change> is a live change id, such as add-renewal-status, or a path such as openspec/changes/add-renewal-status. Archived changes are not resolved by id.
| Command | Output |
| ------------- | -------------------------------------------------------------------------------------------------------------- |
| osi impact | Main evidence pipeline: named seeds, citation references, and history. |
| osi scope | concepts, ranked candidates, and related tests. |
| osi history | seeds and history, with the same history rules as impact; no refs key. |
| osi init | Installs the opsx-impact skill for the selected agents. Detected agents start selected; scripts pass --agent. |
--no-searchkeeps harvested concepts but skips the repository scan. Inscope,candidatesandtestsare empty; inimpact,seeds,refs, andhistoryare empty.--include-lowadds up to 20 low-confidence candidates toscope. The flag is accepted byimpact, but does not add low-confidence rows to its output;impactreports named high-confidence seeds.
osi impact output
The successful output is one YAML document with version, change, seeds, refs, and history at the top level:
version: 1
change:
name: 'add-renewal-status'
path: 'openspec/changes/add-renewal-status'
seeds:
- 'src/pages/tenant/TenantList.tsx'
refs:
- path: 'src/pages/tenant/TenantList.tsx'
term: 'TenantList'
others: 0
wide: false
sample: []
history:
- path: 'src/services/tenant.ts'
via: 'src/pages/tenant/TenantList.tsx'
commits: 2
reason: co_changeseedsare named, high-confidence files that match a citation by filename or symbol. They are starting points, not a complete change list.- Each
refsrow describes the seed's citation term and how often it appears in other source files.otherscounts distinct non-test files with a content or symbol match; it does not measure dependency.samplelists up to 8 example paths.wide: truemeans the term matched content or symbols in more than 80 files;sampleis then empty. historymay containco_changeorsiblingrows. Aco_changeneighbor appeared with the seed in at least 2 qualifying commits in the same Git repository during the last 18 months. Merge commits and commits touching more than 30 files are ignored; each seed contributes at most 10 co-change rows.- If a seed has an enclosing Git root, no qualifying co-change rows, and
refs.othersis below 30,historymay include up to 4 same-directory siblings selected by a limited filename rule or byrefs.sample. A sibling hasreason: siblingandcommits: 0; that value is not historical support. Whenrefs.othersis 30 or more, neither co-change nor sibling expansion runs for that seed. A seed without a Git root has no history rows. - The complete
historylist is capped at 50 rows. History rows have noconfidencescore.
osi scope output
scope returns concepts, candidates, and tests:
version: 1
change:
name: 'add-renewal-status'
path: 'openspec/changes/add-renewal-status'
concepts:
- text: 'TenantList'
candidates:
- path: 'src/pages/tenant/TenantList.tsx'
confidence: high
reasons:
- type: symbol_match
term: 'TenantList'
tests:
- path: 'src/pages/tenant/TenantList.test.tsx'
related_to: 'src/pages/tenant/TenantList.tsx'Search uses explicit typed citations from the change docs: paths, code symbols, HTTP method/path pairs, and permission or configuration codes. It does not turn headings or ordinary prose into search terms, and it drops citations under Out of scope / 不在范围. Candidate confidence is a lexical match category, not a probability that the file must change.
Contributor setup
From a checkout of this repository, build and link the CLI:
npm install
npm run build
npm linkRun the checks from the checkout:
npm test
npm run fmt中文
openspec-impact 提供一个命令行工具,安装后同时叫 osi 和 openspec-impact,为一份进行中的 OpenSpec 变更收集确定性证据。它根据变更文档里的明确引用寻找代码文件,再补充有限的 Git 历史线索。它不会决定哪些文件必须修改,CLI 本身也不调用大模型。
可选的 agent 技能 /opsx-impact 会读取这些证据并生成易读的影响面报告。面向产品经理的介绍见产品说明。
环境要求
- Node.js 18 或更高版本,以及 Git。
rg是可选的。没有rg时,osi会遍历项目文件并直接搜索文件内容。
快速开始
全局安装最新版本:
npm install -g openspec-impact@latest在包含进行中 OpenSpec 变更的目标项目里,为正在使用的 agent 安装影响面技能:
cd your-openspec-project
osi initosi init 会在最近的 OpenSpec 项目根目录检查 Cursor、Claude Code、Codex、Windsurf、Cline、Roo Code、OpenCode、GitHub Copilot 和 Pi 的项目配置。在终端里它会打印命中的路径,列出全部支持的 agent,并预选检测到的项。上下键移动,空格勾选或取消,回车安装。没有检测到时不预选,仍可以手选。只有确认的 agent 会被写入或刷新,其余 agent 文件保持不变。
脚本里传入同样的 id,跳过选择:
osi init --agent cursor,codexAgent id:cursor、claude、codex、windsurf、cline、roo、opencode、github-copilot、pi。stdin 不是终端且没有 --agent 时,osi init 报错退出,不写文件。
在该项目的 agent 对话里,输入进行中的变更名:
/opsx-impact <change-name>例如 /opsx-impact add-renewal-status。Cursor、Claude Code、Windsurf、Cline、Roo Code、OpenCode、GitHub Copilot 和 Pi 使用这条斜杠命令。Codex 使用 $opsx-impact <change-name>。agent 读取证据后,在对话里回复影响面报告。
如需直接在终端获取 YAML 证据,运行:
osi impact add-renewal-status升级全局安装的包后,再次运行 osi init,或带上 --agent,刷新所选文件:
npm install -g openspec-impact@latest
osi init --agent cursor如果安装后找不到 osi 或 openspec-impact,请将 npm 的全局可执行文件目录加入 PATH。在类 Unix 系统中,它是 npm prefix -g 返回目录下的 bin;在 Windows 中则是 npm prefix -g 返回的目录。
命令
osi 和 openspec-impact 运行同一组命令。下面的例子使用 osi。
osi impact [--no-search] [--include-low] <change-id|path>
osi scope [--no-search] [--include-low] <change-id|path>
osi history <change-id|path>
osi init [--agent <id[,id...]>]<change> 可以是进行中的变更 id(如 add-renewal-status),也可以是路径(如 openspec/changes/add-renewal-status)。归档变更不能只靠 id 解析。
| 命令 | 输出 |
| ------------- | -------------------------------------------------------------------------------- |
| osi impact | 默认证据管线:具名种子、引用情况和历史线索。 |
| osi scope | concepts、排序后的 candidates 和相关 tests。 |
| osi history | seeds 和 history,使用与 impact 相同的历史规则,但不输出 refs。 |
| osi init | 为所选 agent 安装 opsx-impact 技能。检测到的 agent 默认选中;脚本使用 --agent。 |
--no-search保留从变更文档抽出的概念,但跳过仓库搜索。scope的candidates和tests会为空;impact的seeds、refs和history会为空。--include-low让scope额外输出最多 20 个低置信度候选。impact虽接受此参数,但不会因此多输出低置信度项;它只报告具名高置信度种子。
osi impact 输出
成功时输出一份 YAML,顶层字段为 version、change、seeds、refs 和 history:
version: 1
change:
name: 'add-renewal-status'
path: 'openspec/changes/add-renewal-status'
seeds:
- 'src/pages/tenant/TenantList.tsx'
refs:
- path: 'src/pages/tenant/TenantList.tsx'
term: 'TenantList'
others: 0
wide: false
sample: []
history:
- path: 'src/services/tenant.ts'
via: 'src/pages/tenant/TenantList.tsx'
commits: 2
reason: co_changeseeds是文件名或符号与文档引用对应、且达到高置信度的文件。它们是核对起点,不是完整改动清单。- 每条
refs说明 seed 对应的引用词及该词在其它源码文件中的出现情况。others统计包含该词的不同非测试文件数,不代表依赖数量。sample最多列 8 个示例路径。若内容或符号命中超过 80 个文件,wide为true,此时sample为空。 history可能包含co_change或sibling。co_change表示同一 Git 仓库内的文件在过去 18 个月里至少 2 次与 seed 出现在同一条符合条件的提交中;合并提交和一次改动超过 30 个文件的提交会被忽略。每个 seed 最多输出 10 条同改记录。- 如果 seed 有所属的 Git 根目录、没有符合条件的同改记录,且
refs.others小于 30,history可能补充最多 4 个同目录文件:按有限的文件名规则匹配,或来自refs.sample。这类行的reason是sibling,commits为 0,不代表有历史同改支持。refs.others达到 30 时,该 seed 不做同改或兄弟文件扩展;没有 Git 根目录的 seed 不会有 history 行。 history总计最多 50 条;历史行没有confidence分数。
osi scope 输出
scope 返回 concepts、candidates 和 tests:
version: 1
change:
name: 'add-renewal-status'
path: 'openspec/changes/add-renewal-status'
concepts:
- text: 'TenantList'
candidates:
- path: 'src/pages/tenant/TenantList.tsx'
confidence: high
reasons:
- type: symbol_match
term: 'TenantList'
tests:
- path: 'src/pages/tenant/TenantList.test.tsx'
related_to: 'src/pages/tenant/TenantList.tsx'搜索词只来自变更文档中明确标记的类型化引用:文件路径、代码符号、HTTP 方法与路径、权限或配置码。标题和普通描述不会被拆成搜索词;Out of scope / 不在范围里的引用会被排除。候选的置信度表示词法匹配档位,不代表文件必须修改的概率。
贡献者设置
在本仓库的 checkout 中构建并链接 CLI:
npm install
npm run build
npm link在 checkout 中运行检查:
npm test
npm run fmt