@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.
Files changed (234) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +204 -0
  3. package/bin/openspec.js +3 -0
  4. package/dist/cli/index.d.ts +2 -0
  5. package/dist/cli/index.js +482 -0
  6. package/dist/commands/change.d.ts +35 -0
  7. package/dist/commands/change.js +277 -0
  8. package/dist/commands/completion.d.ts +72 -0
  9. package/dist/commands/completion.js +257 -0
  10. package/dist/commands/config.d.ts +8 -0
  11. package/dist/commands/config.js +198 -0
  12. package/dist/commands/feedback.d.ts +9 -0
  13. package/dist/commands/feedback.js +183 -0
  14. package/dist/commands/schema.d.ts +6 -0
  15. package/dist/commands/schema.js +869 -0
  16. package/dist/commands/show.d.ts +14 -0
  17. package/dist/commands/show.js +132 -0
  18. package/dist/commands/spec.d.ts +15 -0
  19. package/dist/commands/spec.js +225 -0
  20. package/dist/commands/validate.d.ts +24 -0
  21. package/dist/commands/validate.js +294 -0
  22. package/dist/commands/workflow/index.d.ts +17 -0
  23. package/dist/commands/workflow/index.js +12 -0
  24. package/dist/commands/workflow/instructions.d.ts +29 -0
  25. package/dist/commands/workflow/instructions.js +381 -0
  26. package/dist/commands/workflow/new-change.d.ts +11 -0
  27. package/dist/commands/workflow/new-change.js +44 -0
  28. package/dist/commands/workflow/schemas.d.ts +10 -0
  29. package/dist/commands/workflow/schemas.js +34 -0
  30. package/dist/commands/workflow/shared.d.ts +52 -0
  31. package/dist/commands/workflow/shared.js +111 -0
  32. package/dist/commands/workflow/status.d.ts +14 -0
  33. package/dist/commands/workflow/status.js +58 -0
  34. package/dist/commands/workflow/templates.d.ts +16 -0
  35. package/dist/commands/workflow/templates.js +68 -0
  36. package/dist/core/archive.d.ts +11 -0
  37. package/dist/core/archive.js +328 -0
  38. package/dist/core/artifact-graph/graph.d.ts +56 -0
  39. package/dist/core/artifact-graph/graph.js +141 -0
  40. package/dist/core/artifact-graph/index.d.ts +7 -0
  41. package/dist/core/artifact-graph/index.js +13 -0
  42. package/dist/core/artifact-graph/instruction-loader.d.ts +143 -0
  43. package/dist/core/artifact-graph/instruction-loader.js +214 -0
  44. package/dist/core/artifact-graph/resolver.d.ts +81 -0
  45. package/dist/core/artifact-graph/resolver.js +257 -0
  46. package/dist/core/artifact-graph/schema.d.ts +13 -0
  47. package/dist/core/artifact-graph/schema.js +108 -0
  48. package/dist/core/artifact-graph/state.d.ts +12 -0
  49. package/dist/core/artifact-graph/state.js +54 -0
  50. package/dist/core/artifact-graph/types.d.ts +45 -0
  51. package/dist/core/artifact-graph/types.js +43 -0
  52. package/dist/core/command-generation/adapters/amazon-q.d.ts +13 -0
  53. package/dist/core/command-generation/adapters/amazon-q.js +26 -0
  54. package/dist/core/command-generation/adapters/antigravity.d.ts +13 -0
  55. package/dist/core/command-generation/adapters/antigravity.js +26 -0
  56. package/dist/core/command-generation/adapters/auggie.d.ts +13 -0
  57. package/dist/core/command-generation/adapters/auggie.js +27 -0
  58. package/dist/core/command-generation/adapters/claude.d.ts +13 -0
  59. package/dist/core/command-generation/adapters/claude.js +50 -0
  60. package/dist/core/command-generation/adapters/cline.d.ts +14 -0
  61. package/dist/core/command-generation/adapters/cline.js +27 -0
  62. package/dist/core/command-generation/adapters/codebuddy.d.ts +13 -0
  63. package/dist/core/command-generation/adapters/codebuddy.js +28 -0
  64. package/dist/core/command-generation/adapters/codex.d.ts +16 -0
  65. package/dist/core/command-generation/adapters/codex.js +39 -0
  66. package/dist/core/command-generation/adapters/continue.d.ts +13 -0
  67. package/dist/core/command-generation/adapters/continue.js +28 -0
  68. package/dist/core/command-generation/adapters/costrict.d.ts +13 -0
  69. package/dist/core/command-generation/adapters/costrict.js +27 -0
  70. package/dist/core/command-generation/adapters/crush.d.ts +13 -0
  71. package/dist/core/command-generation/adapters/crush.js +30 -0
  72. package/dist/core/command-generation/adapters/cursor.d.ts +14 -0
  73. package/dist/core/command-generation/adapters/cursor.js +44 -0
  74. package/dist/core/command-generation/adapters/devagent.d.ts +15 -0
  75. package/dist/core/command-generation/adapters/devagent.js +28 -0
  76. package/dist/core/command-generation/adapters/factory.d.ts +13 -0
  77. package/dist/core/command-generation/adapters/factory.js +27 -0
  78. package/dist/core/command-generation/adapters/gemini.d.ts +13 -0
  79. package/dist/core/command-generation/adapters/gemini.js +26 -0
  80. package/dist/core/command-generation/adapters/github-copilot.d.ts +13 -0
  81. package/dist/core/command-generation/adapters/github-copilot.js +26 -0
  82. package/dist/core/command-generation/adapters/iflow.d.ts +13 -0
  83. package/dist/core/command-generation/adapters/iflow.js +29 -0
  84. package/dist/core/command-generation/adapters/index.d.ts +28 -0
  85. package/dist/core/command-generation/adapters/index.js +28 -0
  86. package/dist/core/command-generation/adapters/kilocode.d.ts +14 -0
  87. package/dist/core/command-generation/adapters/kilocode.js +23 -0
  88. package/dist/core/command-generation/adapters/opencode.d.ts +13 -0
  89. package/dist/core/command-generation/adapters/opencode.js +29 -0
  90. package/dist/core/command-generation/adapters/qoder.d.ts +13 -0
  91. package/dist/core/command-generation/adapters/qoder.js +30 -0
  92. package/dist/core/command-generation/adapters/qwen.d.ts +13 -0
  93. package/dist/core/command-generation/adapters/qwen.js +26 -0
  94. package/dist/core/command-generation/adapters/roocode.d.ts +14 -0
  95. package/dist/core/command-generation/adapters/roocode.js +27 -0
  96. package/dist/core/command-generation/adapters/windsurf.d.ts +14 -0
  97. package/dist/core/command-generation/adapters/windsurf.js +51 -0
  98. package/dist/core/command-generation/generator.d.ts +21 -0
  99. package/dist/core/command-generation/generator.js +27 -0
  100. package/dist/core/command-generation/index.d.ts +22 -0
  101. package/dist/core/command-generation/index.js +24 -0
  102. package/dist/core/command-generation/registry.d.ts +36 -0
  103. package/dist/core/command-generation/registry.js +90 -0
  104. package/dist/core/command-generation/types.d.ts +56 -0
  105. package/dist/core/command-generation/types.js +8 -0
  106. package/dist/core/completions/command-registry.d.ts +7 -0
  107. package/dist/core/completions/command-registry.js +454 -0
  108. package/dist/core/completions/completion-provider.d.ts +60 -0
  109. package/dist/core/completions/completion-provider.js +102 -0
  110. package/dist/core/completions/factory.d.ts +64 -0
  111. package/dist/core/completions/factory.js +75 -0
  112. package/dist/core/completions/generators/bash-generator.d.ts +32 -0
  113. package/dist/core/completions/generators/bash-generator.js +174 -0
  114. package/dist/core/completions/generators/fish-generator.d.ts +32 -0
  115. package/dist/core/completions/generators/fish-generator.js +157 -0
  116. package/dist/core/completions/generators/powershell-generator.d.ts +33 -0
  117. package/dist/core/completions/generators/powershell-generator.js +207 -0
  118. package/dist/core/completions/generators/zsh-generator.d.ts +44 -0
  119. package/dist/core/completions/generators/zsh-generator.js +250 -0
  120. package/dist/core/completions/installers/bash-installer.d.ts +87 -0
  121. package/dist/core/completions/installers/bash-installer.js +318 -0
  122. package/dist/core/completions/installers/fish-installer.d.ts +43 -0
  123. package/dist/core/completions/installers/fish-installer.js +143 -0
  124. package/dist/core/completions/installers/powershell-installer.d.ts +88 -0
  125. package/dist/core/completions/installers/powershell-installer.js +327 -0
  126. package/dist/core/completions/installers/zsh-installer.d.ts +125 -0
  127. package/dist/core/completions/installers/zsh-installer.js +449 -0
  128. package/dist/core/completions/templates/bash-templates.d.ts +6 -0
  129. package/dist/core/completions/templates/bash-templates.js +24 -0
  130. package/dist/core/completions/templates/fish-templates.d.ts +7 -0
  131. package/dist/core/completions/templates/fish-templates.js +39 -0
  132. package/dist/core/completions/templates/powershell-templates.d.ts +6 -0
  133. package/dist/core/completions/templates/powershell-templates.js +25 -0
  134. package/dist/core/completions/templates/zsh-templates.d.ts +6 -0
  135. package/dist/core/completions/templates/zsh-templates.js +36 -0
  136. package/dist/core/completions/types.d.ts +79 -0
  137. package/dist/core/completions/types.js +2 -0
  138. package/dist/core/config-prompts.d.ts +9 -0
  139. package/dist/core/config-prompts.js +34 -0
  140. package/dist/core/config-schema.d.ts +76 -0
  141. package/dist/core/config-schema.js +200 -0
  142. package/dist/core/config.d.ts +17 -0
  143. package/dist/core/config.js +175 -0
  144. package/dist/core/converters/json-converter.d.ts +6 -0
  145. package/dist/core/converters/json-converter.js +51 -0
  146. package/dist/core/global-config.d.ts +39 -0
  147. package/dist/core/global-config.js +115 -0
  148. package/dist/core/index.d.ts +2 -0
  149. package/dist/core/index.js +3 -0
  150. package/dist/core/init.d.ts +32 -0
  151. package/dist/core/init.js +447 -0
  152. package/dist/core/legacy-cleanup.d.ts +162 -0
  153. package/dist/core/legacy-cleanup.js +520 -0
  154. package/dist/core/list.d.ts +9 -0
  155. package/dist/core/list.js +171 -0
  156. package/dist/core/parsers/change-parser.d.ts +13 -0
  157. package/dist/core/parsers/change-parser.js +193 -0
  158. package/dist/core/parsers/markdown-parser.d.ts +22 -0
  159. package/dist/core/parsers/markdown-parser.js +187 -0
  160. package/dist/core/parsers/requirement-blocks.d.ts +37 -0
  161. package/dist/core/parsers/requirement-blocks.js +201 -0
  162. package/dist/core/project-config.d.ts +64 -0
  163. package/dist/core/project-config.js +223 -0
  164. package/dist/core/schemas/base.schema.d.ts +13 -0
  165. package/dist/core/schemas/base.schema.js +13 -0
  166. package/dist/core/schemas/change.schema.d.ts +73 -0
  167. package/dist/core/schemas/change.schema.js +31 -0
  168. package/dist/core/schemas/index.d.ts +4 -0
  169. package/dist/core/schemas/index.js +4 -0
  170. package/dist/core/schemas/spec.schema.d.ts +18 -0
  171. package/dist/core/schemas/spec.schema.js +15 -0
  172. package/dist/core/shared/index.d.ts +8 -0
  173. package/dist/core/shared/index.js +8 -0
  174. package/dist/core/shared/skill-generation.d.ts +42 -0
  175. package/dist/core/shared/skill-generation.js +80 -0
  176. package/dist/core/shared/tool-detection.d.ts +66 -0
  177. package/dist/core/shared/tool-detection.js +140 -0
  178. package/dist/core/specs-apply.d.ts +73 -0
  179. package/dist/core/specs-apply.js +384 -0
  180. package/dist/core/styles/palette.d.ts +7 -0
  181. package/dist/core/styles/palette.js +8 -0
  182. package/dist/core/templates/index.d.ts +8 -0
  183. package/dist/core/templates/index.js +9 -0
  184. package/dist/core/templates/skill-templates.d.ts +122 -0
  185. package/dist/core/templates/skill-templates.js +3437 -0
  186. package/dist/core/update.d.ts +42 -0
  187. package/dist/core/update.js +311 -0
  188. package/dist/core/validation/constants.d.ts +34 -0
  189. package/dist/core/validation/constants.js +40 -0
  190. package/dist/core/validation/types.d.ts +18 -0
  191. package/dist/core/validation/types.js +2 -0
  192. package/dist/core/validation/validator.d.ts +33 -0
  193. package/dist/core/validation/validator.js +409 -0
  194. package/dist/core/view.d.ts +8 -0
  195. package/dist/core/view.js +168 -0
  196. package/dist/index.d.ts +3 -0
  197. package/dist/index.js +3 -0
  198. package/dist/prompts/searchable-multi-select.d.ts +27 -0
  199. package/dist/prompts/searchable-multi-select.js +149 -0
  200. package/dist/telemetry/config.d.ts +32 -0
  201. package/dist/telemetry/config.js +68 -0
  202. package/dist/telemetry/index.d.ts +31 -0
  203. package/dist/telemetry/index.js +145 -0
  204. package/dist/ui/ascii-patterns.d.ts +16 -0
  205. package/dist/ui/ascii-patterns.js +133 -0
  206. package/dist/ui/welcome-screen.d.ts +10 -0
  207. package/dist/ui/welcome-screen.js +146 -0
  208. package/dist/utils/change-metadata.d.ts +51 -0
  209. package/dist/utils/change-metadata.js +147 -0
  210. package/dist/utils/change-utils.d.ts +62 -0
  211. package/dist/utils/change-utils.js +121 -0
  212. package/dist/utils/command-references.d.ts +18 -0
  213. package/dist/utils/command-references.js +20 -0
  214. package/dist/utils/file-system.d.ts +36 -0
  215. package/dist/utils/file-system.js +281 -0
  216. package/dist/utils/index.d.ts +6 -0
  217. package/dist/utils/index.js +9 -0
  218. package/dist/utils/interactive.d.ts +18 -0
  219. package/dist/utils/interactive.js +21 -0
  220. package/dist/utils/item-discovery.d.ts +4 -0
  221. package/dist/utils/item-discovery.js +72 -0
  222. package/dist/utils/match.d.ts +3 -0
  223. package/dist/utils/match.js +22 -0
  224. package/dist/utils/shell-detection.d.ts +20 -0
  225. package/dist/utils/shell-detection.js +41 -0
  226. package/dist/utils/task-progress.d.ts +8 -0
  227. package/dist/utils/task-progress.js +36 -0
  228. package/package.json +83 -0
  229. package/schemas/spec-driven/schema.yaml +151 -0
  230. package/schemas/spec-driven/templates/design.md +21 -0
  231. package/schemas/spec-driven/templates/proposal.md +25 -0
  232. package/schemas/spec-driven/templates/spec.md +10 -0
  233. package/schemas/spec-driven/templates/tasks.md +9 -0
  234. 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,21 @@
1
+ ## 背景
2
+
3
+ <!-- 背景与当前状态 -->
4
+
5
+ ## 目标 / 非目标
6
+
7
+ **目标:**
8
+
9
+ <!-- 本设计要达成的结果 -->
10
+
11
+ **非目标:**
12
+
13
+ <!-- 明确不在范围内的内容 -->
14
+
15
+ ## 决策
16
+
17
+ <!-- 关键设计决策及理由 -->
18
+
19
+ ## 风险 / 权衡
20
+
21
+ <!-- 已知风险与权衡 -->
@@ -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,10 @@
1
+ ## ADDED Requirements
2
+
3
+ ### Requirement: <!-- 需求名称 -->
4
+
5
+ <!-- 需求正文 -->
6
+
7
+ #### Scenario: <!-- 场景名称 -->
8
+
9
+ - **WHEN** <!-- 条件 -->
10
+ - **THEN** <!-- 预期结果 -->
@@ -0,0 +1,9 @@
1
+ ## 1. <!-- 任务组名称 -->
2
+
3
+ - [ ] 1.1 <!-- 任务描述 -->
4
+ - [ ] 1.2 <!-- 任务描述 -->
5
+
6
+ ## 2. <!-- 任务组名称 -->
7
+
8
+ - [ ] 2.1 <!-- 任务描述 -->
9
+ - [ ] 2.2 <!-- 任务描述 -->
@@ -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
+ });