@bobby_z/openspec 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +22 -0
- package/README.md +204 -0
- package/bin/openspec.js +3 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +482 -0
- package/dist/commands/change.d.ts +35 -0
- package/dist/commands/change.js +277 -0
- package/dist/commands/completion.d.ts +72 -0
- package/dist/commands/completion.js +257 -0
- package/dist/commands/config.d.ts +8 -0
- package/dist/commands/config.js +198 -0
- package/dist/commands/feedback.d.ts +9 -0
- package/dist/commands/feedback.js +183 -0
- package/dist/commands/schema.d.ts +6 -0
- package/dist/commands/schema.js +869 -0
- package/dist/commands/show.d.ts +14 -0
- package/dist/commands/show.js +132 -0
- package/dist/commands/spec.d.ts +15 -0
- package/dist/commands/spec.js +225 -0
- package/dist/commands/validate.d.ts +24 -0
- package/dist/commands/validate.js +294 -0
- package/dist/commands/workflow/index.d.ts +17 -0
- package/dist/commands/workflow/index.js +12 -0
- package/dist/commands/workflow/instructions.d.ts +29 -0
- package/dist/commands/workflow/instructions.js +381 -0
- package/dist/commands/workflow/new-change.d.ts +11 -0
- package/dist/commands/workflow/new-change.js +44 -0
- package/dist/commands/workflow/schemas.d.ts +10 -0
- package/dist/commands/workflow/schemas.js +34 -0
- package/dist/commands/workflow/shared.d.ts +52 -0
- package/dist/commands/workflow/shared.js +111 -0
- package/dist/commands/workflow/status.d.ts +14 -0
- package/dist/commands/workflow/status.js +58 -0
- package/dist/commands/workflow/templates.d.ts +16 -0
- package/dist/commands/workflow/templates.js +68 -0
- package/dist/core/archive.d.ts +11 -0
- package/dist/core/archive.js +328 -0
- package/dist/core/artifact-graph/graph.d.ts +56 -0
- package/dist/core/artifact-graph/graph.js +141 -0
- package/dist/core/artifact-graph/index.d.ts +7 -0
- package/dist/core/artifact-graph/index.js +13 -0
- package/dist/core/artifact-graph/instruction-loader.d.ts +143 -0
- package/dist/core/artifact-graph/instruction-loader.js +214 -0
- package/dist/core/artifact-graph/resolver.d.ts +81 -0
- package/dist/core/artifact-graph/resolver.js +257 -0
- package/dist/core/artifact-graph/schema.d.ts +13 -0
- package/dist/core/artifact-graph/schema.js +108 -0
- package/dist/core/artifact-graph/state.d.ts +12 -0
- package/dist/core/artifact-graph/state.js +54 -0
- package/dist/core/artifact-graph/types.d.ts +45 -0
- package/dist/core/artifact-graph/types.js +43 -0
- package/dist/core/command-generation/adapters/amazon-q.d.ts +13 -0
- package/dist/core/command-generation/adapters/amazon-q.js +26 -0
- package/dist/core/command-generation/adapters/antigravity.d.ts +13 -0
- package/dist/core/command-generation/adapters/antigravity.js +26 -0
- package/dist/core/command-generation/adapters/auggie.d.ts +13 -0
- package/dist/core/command-generation/adapters/auggie.js +27 -0
- package/dist/core/command-generation/adapters/claude.d.ts +13 -0
- package/dist/core/command-generation/adapters/claude.js +50 -0
- package/dist/core/command-generation/adapters/cline.d.ts +14 -0
- package/dist/core/command-generation/adapters/cline.js +27 -0
- package/dist/core/command-generation/adapters/codebuddy.d.ts +13 -0
- package/dist/core/command-generation/adapters/codebuddy.js +28 -0
- package/dist/core/command-generation/adapters/codex.d.ts +16 -0
- package/dist/core/command-generation/adapters/codex.js +39 -0
- package/dist/core/command-generation/adapters/continue.d.ts +13 -0
- package/dist/core/command-generation/adapters/continue.js +28 -0
- package/dist/core/command-generation/adapters/costrict.d.ts +13 -0
- package/dist/core/command-generation/adapters/costrict.js +27 -0
- package/dist/core/command-generation/adapters/crush.d.ts +13 -0
- package/dist/core/command-generation/adapters/crush.js +30 -0
- package/dist/core/command-generation/adapters/cursor.d.ts +14 -0
- package/dist/core/command-generation/adapters/cursor.js +44 -0
- package/dist/core/command-generation/adapters/devagent.d.ts +15 -0
- package/dist/core/command-generation/adapters/devagent.js +28 -0
- package/dist/core/command-generation/adapters/factory.d.ts +13 -0
- package/dist/core/command-generation/adapters/factory.js +27 -0
- package/dist/core/command-generation/adapters/gemini.d.ts +13 -0
- package/dist/core/command-generation/adapters/gemini.js +26 -0
- package/dist/core/command-generation/adapters/github-copilot.d.ts +13 -0
- package/dist/core/command-generation/adapters/github-copilot.js +26 -0
- package/dist/core/command-generation/adapters/iflow.d.ts +13 -0
- package/dist/core/command-generation/adapters/iflow.js +29 -0
- package/dist/core/command-generation/adapters/index.d.ts +28 -0
- package/dist/core/command-generation/adapters/index.js +28 -0
- package/dist/core/command-generation/adapters/kilocode.d.ts +14 -0
- package/dist/core/command-generation/adapters/kilocode.js +23 -0
- package/dist/core/command-generation/adapters/opencode.d.ts +13 -0
- package/dist/core/command-generation/adapters/opencode.js +29 -0
- package/dist/core/command-generation/adapters/qoder.d.ts +13 -0
- package/dist/core/command-generation/adapters/qoder.js +30 -0
- package/dist/core/command-generation/adapters/qwen.d.ts +13 -0
- package/dist/core/command-generation/adapters/qwen.js +26 -0
- package/dist/core/command-generation/adapters/roocode.d.ts +14 -0
- package/dist/core/command-generation/adapters/roocode.js +27 -0
- package/dist/core/command-generation/adapters/windsurf.d.ts +14 -0
- package/dist/core/command-generation/adapters/windsurf.js +51 -0
- package/dist/core/command-generation/generator.d.ts +21 -0
- package/dist/core/command-generation/generator.js +27 -0
- package/dist/core/command-generation/index.d.ts +22 -0
- package/dist/core/command-generation/index.js +24 -0
- package/dist/core/command-generation/registry.d.ts +36 -0
- package/dist/core/command-generation/registry.js +90 -0
- package/dist/core/command-generation/types.d.ts +56 -0
- package/dist/core/command-generation/types.js +8 -0
- package/dist/core/completions/command-registry.d.ts +7 -0
- package/dist/core/completions/command-registry.js +454 -0
- package/dist/core/completions/completion-provider.d.ts +60 -0
- package/dist/core/completions/completion-provider.js +102 -0
- package/dist/core/completions/factory.d.ts +64 -0
- package/dist/core/completions/factory.js +75 -0
- package/dist/core/completions/generators/bash-generator.d.ts +32 -0
- package/dist/core/completions/generators/bash-generator.js +174 -0
- package/dist/core/completions/generators/fish-generator.d.ts +32 -0
- package/dist/core/completions/generators/fish-generator.js +157 -0
- package/dist/core/completions/generators/powershell-generator.d.ts +33 -0
- package/dist/core/completions/generators/powershell-generator.js +207 -0
- package/dist/core/completions/generators/zsh-generator.d.ts +44 -0
- package/dist/core/completions/generators/zsh-generator.js +250 -0
- package/dist/core/completions/installers/bash-installer.d.ts +87 -0
- package/dist/core/completions/installers/bash-installer.js +318 -0
- package/dist/core/completions/installers/fish-installer.d.ts +43 -0
- package/dist/core/completions/installers/fish-installer.js +143 -0
- package/dist/core/completions/installers/powershell-installer.d.ts +88 -0
- package/dist/core/completions/installers/powershell-installer.js +327 -0
- package/dist/core/completions/installers/zsh-installer.d.ts +125 -0
- package/dist/core/completions/installers/zsh-installer.js +449 -0
- package/dist/core/completions/templates/bash-templates.d.ts +6 -0
- package/dist/core/completions/templates/bash-templates.js +24 -0
- package/dist/core/completions/templates/fish-templates.d.ts +7 -0
- package/dist/core/completions/templates/fish-templates.js +39 -0
- package/dist/core/completions/templates/powershell-templates.d.ts +6 -0
- package/dist/core/completions/templates/powershell-templates.js +25 -0
- package/dist/core/completions/templates/zsh-templates.d.ts +6 -0
- package/dist/core/completions/templates/zsh-templates.js +36 -0
- package/dist/core/completions/types.d.ts +79 -0
- package/dist/core/completions/types.js +2 -0
- package/dist/core/config-prompts.d.ts +9 -0
- package/dist/core/config-prompts.js +34 -0
- package/dist/core/config-schema.d.ts +76 -0
- package/dist/core/config-schema.js +200 -0
- package/dist/core/config.d.ts +17 -0
- package/dist/core/config.js +175 -0
- package/dist/core/converters/json-converter.d.ts +6 -0
- package/dist/core/converters/json-converter.js +51 -0
- package/dist/core/global-config.d.ts +39 -0
- package/dist/core/global-config.js +115 -0
- package/dist/core/index.d.ts +2 -0
- package/dist/core/index.js +3 -0
- package/dist/core/init.d.ts +32 -0
- package/dist/core/init.js +447 -0
- package/dist/core/legacy-cleanup.d.ts +162 -0
- package/dist/core/legacy-cleanup.js +520 -0
- package/dist/core/list.d.ts +9 -0
- package/dist/core/list.js +171 -0
- package/dist/core/parsers/change-parser.d.ts +13 -0
- package/dist/core/parsers/change-parser.js +193 -0
- package/dist/core/parsers/markdown-parser.d.ts +22 -0
- package/dist/core/parsers/markdown-parser.js +187 -0
- package/dist/core/parsers/requirement-blocks.d.ts +37 -0
- package/dist/core/parsers/requirement-blocks.js +201 -0
- package/dist/core/project-config.d.ts +64 -0
- package/dist/core/project-config.js +223 -0
- package/dist/core/schemas/base.schema.d.ts +13 -0
- package/dist/core/schemas/base.schema.js +13 -0
- package/dist/core/schemas/change.schema.d.ts +73 -0
- package/dist/core/schemas/change.schema.js +31 -0
- package/dist/core/schemas/index.d.ts +4 -0
- package/dist/core/schemas/index.js +4 -0
- package/dist/core/schemas/spec.schema.d.ts +18 -0
- package/dist/core/schemas/spec.schema.js +15 -0
- package/dist/core/shared/index.d.ts +8 -0
- package/dist/core/shared/index.js +8 -0
- package/dist/core/shared/skill-generation.d.ts +42 -0
- package/dist/core/shared/skill-generation.js +80 -0
- package/dist/core/shared/tool-detection.d.ts +66 -0
- package/dist/core/shared/tool-detection.js +140 -0
- package/dist/core/specs-apply.d.ts +73 -0
- package/dist/core/specs-apply.js +384 -0
- package/dist/core/styles/palette.d.ts +7 -0
- package/dist/core/styles/palette.js +8 -0
- package/dist/core/templates/index.d.ts +8 -0
- package/dist/core/templates/index.js +9 -0
- package/dist/core/templates/skill-templates.d.ts +122 -0
- package/dist/core/templates/skill-templates.js +3437 -0
- package/dist/core/update.d.ts +42 -0
- package/dist/core/update.js +311 -0
- package/dist/core/validation/constants.d.ts +34 -0
- package/dist/core/validation/constants.js +40 -0
- package/dist/core/validation/types.d.ts +18 -0
- package/dist/core/validation/types.js +2 -0
- package/dist/core/validation/validator.d.ts +33 -0
- package/dist/core/validation/validator.js +409 -0
- package/dist/core/view.d.ts +8 -0
- package/dist/core/view.js +168 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/dist/prompts/searchable-multi-select.d.ts +27 -0
- package/dist/prompts/searchable-multi-select.js +149 -0
- package/dist/telemetry/config.d.ts +32 -0
- package/dist/telemetry/config.js +68 -0
- package/dist/telemetry/index.d.ts +31 -0
- package/dist/telemetry/index.js +145 -0
- package/dist/ui/ascii-patterns.d.ts +16 -0
- package/dist/ui/ascii-patterns.js +133 -0
- package/dist/ui/welcome-screen.d.ts +10 -0
- package/dist/ui/welcome-screen.js +146 -0
- package/dist/utils/change-metadata.d.ts +51 -0
- package/dist/utils/change-metadata.js +147 -0
- package/dist/utils/change-utils.d.ts +62 -0
- package/dist/utils/change-utils.js +121 -0
- package/dist/utils/command-references.d.ts +18 -0
- package/dist/utils/command-references.js +20 -0
- package/dist/utils/file-system.d.ts +36 -0
- package/dist/utils/file-system.js +281 -0
- package/dist/utils/index.d.ts +6 -0
- package/dist/utils/index.js +9 -0
- package/dist/utils/interactive.d.ts +18 -0
- package/dist/utils/interactive.js +21 -0
- package/dist/utils/item-discovery.d.ts +4 -0
- package/dist/utils/item-discovery.js +72 -0
- package/dist/utils/match.d.ts +3 -0
- package/dist/utils/match.js +22 -0
- package/dist/utils/shell-detection.d.ts +20 -0
- package/dist/utils/shell-detection.js +41 -0
- package/dist/utils/task-progress.d.ts +8 -0
- package/dist/utils/task-progress.js +36 -0
- package/package.json +83 -0
- package/schemas/spec-driven/schema.yaml +151 -0
- package/schemas/spec-driven/templates/design.md +21 -0
- package/schemas/spec-driven/templates/proposal.md +25 -0
- package/schemas/spec-driven/templates/spec.md +10 -0
- package/schemas/spec-driven/templates/tasks.md +9 -0
- package/scripts/postinstall.js +147 -0
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
name: spec-driven
|
|
2
|
+
version: 1
|
|
3
|
+
description: 默认 OpenSpec 工作流 - 提案 → 规范 → 设计 → 任务
|
|
4
|
+
artifacts:
|
|
5
|
+
- id: proposal
|
|
6
|
+
generates: proposal.md
|
|
7
|
+
description: 概述本变更的初始提案文档
|
|
8
|
+
template: proposal.md
|
|
9
|
+
instruction: |
|
|
10
|
+
撰写建立「为何需要本变更」的提案文档。
|
|
11
|
+
|
|
12
|
+
章节:
|
|
13
|
+
- **动机**:用 1~2 句话说明问题或机会。解决什么问题?为什么是现在?
|
|
14
|
+
- **变更内容**:变更的要点列表。对新能力、修改或移除保持具体。破坏性变更用 **BREAKING** 标出。
|
|
15
|
+
- **能力**:标明将新增或修改的规范:
|
|
16
|
+
- **新增能力**:列出将要引入的能力。每项对应新的 `specs/<name>/spec.md`。使用 kebab-case 名称(如 `user-auth`、`data-export`)。
|
|
17
|
+
- **修改的能力**:其「需求」会发生变化的既有能力。仅当规范级行为变化时列入(而非仅实现细节)。每项需有对应的增量规范文件。在 `openspec/specs/` 中查看已有规范名称。若无需求级变化可留空。
|
|
18
|
+
- **影响**:受影响的代码、API、依赖或系统。
|
|
19
|
+
|
|
20
|
+
重要:能力一节是提案与规范阶段之间的契约,填写前请先查阅现有规范。
|
|
21
|
+
此处列出的每项能力都需有对应的规范文件。
|
|
22
|
+
|
|
23
|
+
保持简洁(1~2 页)。聚焦「为什么」而非「怎么做」——
|
|
24
|
+
实现细节放在 design.md。
|
|
25
|
+
|
|
26
|
+
这是基础——规范、设计和任务都建立在此之上。
|
|
27
|
+
requires: []
|
|
28
|
+
|
|
29
|
+
- id: specs
|
|
30
|
+
generates: "specs/**/*.md"
|
|
31
|
+
description: 本变更的详细规范
|
|
32
|
+
template: spec.md
|
|
33
|
+
instruction: |
|
|
34
|
+
创建定义「系统应做什么」的规范文件。
|
|
35
|
+
|
|
36
|
+
按提案中「能力」一节列出的每项能力各写一个规范文件。
|
|
37
|
+
- 新增能力:使用提案中的 kebab-case 名称(specs/<capability>/spec.md)。
|
|
38
|
+
- 修改的能力:使用 openspec/specs/<capability>/ 下已有规范目录名,在变更目录下创建增量规范 specs/<capability>/spec.md。
|
|
39
|
+
|
|
40
|
+
增量操作(使用 ## 标题):
|
|
41
|
+
- **ADDED Requirements**:新增能力
|
|
42
|
+
- **MODIFIED Requirements**:行为变更——必须包含完整更新后的内容
|
|
43
|
+
- **REMOVED Requirements**:废弃项——必须包含 **Reason** 与 **Migration**
|
|
44
|
+
- **RENAMED Requirements**:仅名称变更——使用 FROM:/TO: 格式
|
|
45
|
+
|
|
46
|
+
需求格式:
|
|
47
|
+
- 每条需求:`### Requirement: <name>` 后跟描述
|
|
48
|
+
- 规范性需求使用 SHALL/MUST(避免 should/may)
|
|
49
|
+
- 每个场景:`#### Scenario: <name>`,采用 WHEN/THEN 格式
|
|
50
|
+
- **关键**:场景必须使用恰好 4 个井号(`####`)。使用 3 个井号或列表会导致静默失败。
|
|
51
|
+
- 每条需求至少有一个场景。
|
|
52
|
+
|
|
53
|
+
MODIFIED 需求的操作步骤:
|
|
54
|
+
1. 在 openspec/specs/<capability>/spec.md 中找到现有需求
|
|
55
|
+
2. 复制整条需求块(从 `### Requirement:` 到其下所有场景)
|
|
56
|
+
3. 粘贴到 `## MODIFIED Requirements` 下并修改为新行为
|
|
57
|
+
4. 确保标题文字完全匹配(忽略首尾空白)
|
|
58
|
+
|
|
59
|
+
常见错误:MODIFIED 只写部分内容会在归档时丢失细节。
|
|
60
|
+
若只新增关注点而不改既有行为,请使用 ADDED。
|
|
61
|
+
|
|
62
|
+
示例:
|
|
63
|
+
```
|
|
64
|
+
## ADDED Requirements
|
|
65
|
+
|
|
66
|
+
### Requirement: User can export data
|
|
67
|
+
The system SHALL allow users to export their data in CSV format.
|
|
68
|
+
|
|
69
|
+
#### Scenario: Successful export
|
|
70
|
+
- **WHEN** user clicks "Export" button
|
|
71
|
+
- **THEN** system downloads a CSV file with all user data
|
|
72
|
+
|
|
73
|
+
## REMOVED Requirements
|
|
74
|
+
|
|
75
|
+
### Requirement: Legacy export
|
|
76
|
+
**Reason**: Replaced by new export system
|
|
77
|
+
**Migration**: Use new export endpoint at /api/v2/export
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
规范应可检验——每个场景都是潜在测试用例。
|
|
81
|
+
requires:
|
|
82
|
+
- proposal
|
|
83
|
+
|
|
84
|
+
- id: design
|
|
85
|
+
generates: design.md
|
|
86
|
+
description: 含实现细节的技术设计文档
|
|
87
|
+
template: design.md
|
|
88
|
+
instruction: |
|
|
89
|
+
撰写说明「如何实现本变更」的设计文档。
|
|
90
|
+
|
|
91
|
+
何时需要 design.md(仅当符合下列任一情况时创建):
|
|
92
|
+
- 跨模块变更(多服务/多模块)或新架构模式
|
|
93
|
+
- 新增外部依赖或显著数据模型变更
|
|
94
|
+
- 安全、性能或迁移复杂度
|
|
95
|
+
- 需要在编码前做技术决策以消除歧义
|
|
96
|
+
|
|
97
|
+
章节:
|
|
98
|
+
- **背景**:背景、现状、约束、干系人
|
|
99
|
+
- **目标 / 非目标**:本设计要达成的结果及明确排除的内容
|
|
100
|
+
- **决策**:关键技术选择及理由(为何选 X 而非 Y?)。每项决策可简述考虑过的替代方案。
|
|
101
|
+
- **风险 / 权衡**:已知限制与可能问题。格式:[风险] → 缓解措施
|
|
102
|
+
- **迁移计划**:部署步骤、回滚策略(若适用)
|
|
103
|
+
- **待决问题**:尚未确定的决策或未知项
|
|
104
|
+
|
|
105
|
+
聚焦架构与方案,而非逐行实现。
|
|
106
|
+
动机参考提案,需求参考规范。
|
|
107
|
+
|
|
108
|
+
好的设计文档会解释技术决策背后的「为什么」。
|
|
109
|
+
requires:
|
|
110
|
+
- proposal
|
|
111
|
+
|
|
112
|
+
- id: tasks
|
|
113
|
+
generates: tasks.md
|
|
114
|
+
description: 可跟踪的实施任务清单
|
|
115
|
+
template: tasks.md
|
|
116
|
+
instruction: |
|
|
117
|
+
创建拆解实施工作的任务列表。
|
|
118
|
+
|
|
119
|
+
**重要:请严格按下列模板书写。** 应用阶段会解析勾选格式以跟踪进度,未使用 `- [ ]` 的任务不会被跟踪。
|
|
120
|
+
|
|
121
|
+
要点:
|
|
122
|
+
- 在 ## 编号标题下分组相关任务
|
|
123
|
+
- 每条任务必须是勾选项:`- [ ] X.Y 任务描述`
|
|
124
|
+
- 任务粒度以单次会话能完成为宜
|
|
125
|
+
- 按依赖顺序排列(什么必须先做?)
|
|
126
|
+
|
|
127
|
+
示例:
|
|
128
|
+
```
|
|
129
|
+
## 1. Setup
|
|
130
|
+
|
|
131
|
+
- [ ] 1.1 Create new module structure
|
|
132
|
+
- [ ] 1.2 Add dependencies to package.json
|
|
133
|
+
|
|
134
|
+
## 2. Core Implementation
|
|
135
|
+
|
|
136
|
+
- [ ] 2.1 Implement data export function
|
|
137
|
+
- [ ] 2.2 Add CSV formatting utilities
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
要做什么参考规范,怎么做参考设计。
|
|
141
|
+
每条任务应可验证——完成时能明确判断。
|
|
142
|
+
requires:
|
|
143
|
+
- specs
|
|
144
|
+
- design
|
|
145
|
+
|
|
146
|
+
apply:
|
|
147
|
+
requires: [tasks]
|
|
148
|
+
tracks: tasks.md
|
|
149
|
+
instruction: |
|
|
150
|
+
阅读上下文文件,按顺序处理未完成任务,完成即勾选。
|
|
151
|
+
若遇阻塞或需要澄清,请先暂停。
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
## 动机
|
|
2
|
+
|
|
3
|
+
<!-- 说明本变更的动机。要解决什么问题?为什么是现在? -->
|
|
4
|
+
|
|
5
|
+
## 变更内容
|
|
6
|
+
|
|
7
|
+
<!-- 描述将要发生的变化。对新能力、修改或移除保持具体。 -->
|
|
8
|
+
|
|
9
|
+
## 能力
|
|
10
|
+
|
|
11
|
+
### 新增能力
|
|
12
|
+
|
|
13
|
+
<!-- 将要引入的能力。将 <name> 替换为 kebab-case 标识(如 user-auth、data-export、api-rate-limiting)。每项对应 specs/<name>/spec.md -->
|
|
14
|
+
|
|
15
|
+
- `<name>`: <该能力涵盖内容的简要说明>
|
|
16
|
+
|
|
17
|
+
### 修改的能力
|
|
18
|
+
|
|
19
|
+
<!-- 其「需求」会发生变化的既有能力(而非仅实现层面)。仅在规范级行为变化时列入。每项需有对应的增量规范文件。使用 openspec/specs/ 下已有规范名称。若无需求级变化可留空。 -->
|
|
20
|
+
|
|
21
|
+
- `<existing-name>`: <正在变更的需求说明>
|
|
22
|
+
|
|
23
|
+
## 影响
|
|
24
|
+
|
|
25
|
+
<!-- 受影响的代码、API、依赖或系统 -->
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Postinstall script for auto-installing shell completions
|
|
5
|
+
*
|
|
6
|
+
* This script runs automatically after npm install unless:
|
|
7
|
+
* - CI=true environment variable is set
|
|
8
|
+
* - OPENSPEC_NO_COMPLETIONS=1 environment variable is set
|
|
9
|
+
* - dist/ directory doesn't exist (dev setup scenario)
|
|
10
|
+
*
|
|
11
|
+
* The script never fails npm install - all errors are caught and handled gracefully.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { promises as fs } from 'fs';
|
|
15
|
+
import path from 'path';
|
|
16
|
+
import { fileURLToPath } from 'url';
|
|
17
|
+
|
|
18
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
19
|
+
const __dirname = path.dirname(__filename);
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Check if we should skip installation
|
|
23
|
+
*/
|
|
24
|
+
function shouldSkipInstallation() {
|
|
25
|
+
// Skip in CI environments
|
|
26
|
+
if (process.env.CI === 'true' || process.env.CI === '1') {
|
|
27
|
+
return { skip: true, reason: 'CI environment detected' };
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Skip if user opted out
|
|
31
|
+
if (process.env.OPENSPEC_NO_COMPLETIONS === '1') {
|
|
32
|
+
return { skip: true, reason: 'OPENSPEC_NO_COMPLETIONS=1 set' };
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return { skip: false };
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Check if dist/ directory exists
|
|
40
|
+
*/
|
|
41
|
+
async function distExists() {
|
|
42
|
+
const distPath = path.join(__dirname, '..', 'dist');
|
|
43
|
+
try {
|
|
44
|
+
const stat = await fs.stat(distPath);
|
|
45
|
+
return stat.isDirectory();
|
|
46
|
+
} catch {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Detect the user's shell
|
|
53
|
+
*/
|
|
54
|
+
async function detectShell() {
|
|
55
|
+
try {
|
|
56
|
+
const { detectShell } = await import('../dist/utils/shell-detection.js');
|
|
57
|
+
const result = detectShell();
|
|
58
|
+
return result.shell;
|
|
59
|
+
} catch (error) {
|
|
60
|
+
// Fail silently if detection module doesn't exist
|
|
61
|
+
return undefined;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Install completions for the detected shell
|
|
67
|
+
*/
|
|
68
|
+
async function installCompletions(shell) {
|
|
69
|
+
try {
|
|
70
|
+
const { CompletionFactory } = await import('../dist/core/completions/factory.js');
|
|
71
|
+
const { COMMAND_REGISTRY } = await import('../dist/core/completions/command-registry.js');
|
|
72
|
+
|
|
73
|
+
// Check if shell is supported
|
|
74
|
+
if (!CompletionFactory.isSupported(shell)) {
|
|
75
|
+
console.log(`\nTip: Run 'openspec completion install' for shell completions`);
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Generate completion script
|
|
80
|
+
const generator = CompletionFactory.createGenerator(shell);
|
|
81
|
+
const script = generator.generate(COMMAND_REGISTRY);
|
|
82
|
+
|
|
83
|
+
// Install completion script
|
|
84
|
+
const installer = CompletionFactory.createInstaller(shell);
|
|
85
|
+
const result = await installer.install(script);
|
|
86
|
+
|
|
87
|
+
if (result.success) {
|
|
88
|
+
// Show success message based on installation type
|
|
89
|
+
if (result.isOhMyZsh) {
|
|
90
|
+
console.log(`✓ Shell completions installed`);
|
|
91
|
+
console.log(` Restart shell: exec zsh`);
|
|
92
|
+
} else if (result.zshrcConfigured) {
|
|
93
|
+
console.log(`✓ Shell completions installed and configured`);
|
|
94
|
+
console.log(` Restart shell: exec zsh`);
|
|
95
|
+
} else {
|
|
96
|
+
console.log(`✓ Shell completions installed to ~/.zsh/completions/`);
|
|
97
|
+
console.log(` Add to ~/.zshrc: fpath=(~/.zsh/completions $fpath)`);
|
|
98
|
+
console.log(` Then: exec zsh`);
|
|
99
|
+
}
|
|
100
|
+
} else {
|
|
101
|
+
// Installation failed, show tip for manual install
|
|
102
|
+
console.log(`\nTip: Run 'openspec completion install' for shell completions`);
|
|
103
|
+
}
|
|
104
|
+
} catch (error) {
|
|
105
|
+
// Fail gracefully - show tip for manual install
|
|
106
|
+
console.log(`\nTip: Run 'openspec completion install' for shell completions`);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Main function
|
|
112
|
+
*/
|
|
113
|
+
async function main() {
|
|
114
|
+
try {
|
|
115
|
+
// Check if we should skip
|
|
116
|
+
const skipCheck = shouldSkipInstallation();
|
|
117
|
+
if (skipCheck.skip) {
|
|
118
|
+
// Silent skip - no output
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Check if dist/ exists (skip silently if not - expected during dev setup)
|
|
123
|
+
if (!(await distExists())) {
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Detect shell
|
|
128
|
+
const shell = await detectShell();
|
|
129
|
+
if (!shell) {
|
|
130
|
+
console.log(`\nTip: Run 'openspec completion install' for shell completions`);
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Install completions
|
|
135
|
+
await installCompletions(shell);
|
|
136
|
+
} catch (error) {
|
|
137
|
+
// Fail gracefully - never break npm install
|
|
138
|
+
// Show tip for manual install
|
|
139
|
+
console.log(`\nTip: Run 'openspec completion install' for shell completions`);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// Run main and handle any unhandled errors
|
|
144
|
+
main().catch(() => {
|
|
145
|
+
// Silent failure - never break npm install
|
|
146
|
+
process.exit(0);
|
|
147
|
+
});
|