@codewalla_india/openspec 1.3.0 → 1.3.2

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 (333) hide show
  1. package/LICENSE +22 -22
  2. package/README.md +272 -230
  3. package/bin/openspec.js +5 -5
  4. package/dist/cli/index.js +99 -62
  5. package/dist/commands/change.d.ts +0 -2
  6. package/dist/commands/change.js +107 -86
  7. package/dist/commands/config.js +14 -16
  8. package/dist/commands/doctor.js +9 -4
  9. package/dist/commands/feedback.js +79 -30
  10. package/dist/commands/modify.d.ts +26 -0
  11. package/dist/commands/modify.js +147 -0
  12. package/dist/commands/schema.js +170 -91
  13. package/dist/commands/show.js +5 -2
  14. package/dist/commands/spec.js +49 -29
  15. package/dist/commands/store.js +15 -21
  16. package/dist/commands/validate.d.ts +8 -0
  17. package/dist/commands/validate.js +43 -20
  18. package/dist/commands/workflow/index.d.ts +2 -2
  19. package/dist/commands/workflow/index.js +1 -1
  20. package/dist/commands/workflow/instructions.d.ts +6 -26
  21. package/dist/commands/workflow/instructions.js +183 -376
  22. package/dist/commands/workflow/new-change.d.ts +0 -4
  23. package/dist/commands/workflow/new-change.js +10 -28
  24. package/dist/commands/workflow/shared.d.ts +34 -19
  25. package/dist/commands/workflow/shared.js +34 -4
  26. package/dist/commands/workflow/status.js +10 -32
  27. package/dist/commands/workflow/templates.js +15 -5
  28. package/dist/commands/workset.d.ts +2 -2
  29. package/dist/commands/workset.js +19 -22
  30. package/dist/comprehension-quiz/fingerprint.d.ts +39 -0
  31. package/dist/comprehension-quiz/fingerprint.js +84 -0
  32. package/dist/comprehension-quiz/index.d.ts +42 -0
  33. package/dist/comprehension-quiz/index.js +47 -0
  34. package/dist/comprehension-quiz/pass-record.d.ts +44 -0
  35. package/dist/comprehension-quiz/pass-record.js +98 -0
  36. package/dist/comprehension-quiz/providers/anthropic.d.ts +34 -0
  37. package/dist/comprehension-quiz/providers/anthropic.js +53 -0
  38. package/dist/comprehension-quiz/providers/factory.d.ts +44 -0
  39. package/dist/comprehension-quiz/providers/factory.js +174 -0
  40. package/dist/comprehension-quiz/providers/interface.d.ts +59 -0
  41. package/dist/comprehension-quiz/providers/interface.js +63 -0
  42. package/dist/comprehension-quiz/providers/local.d.ts +34 -0
  43. package/dist/comprehension-quiz/providers/local.js +53 -0
  44. package/dist/comprehension-quiz/providers/ollama.d.ts +34 -0
  45. package/dist/comprehension-quiz/providers/ollama.js +53 -0
  46. package/dist/comprehension-quiz/providers/openai.d.ts +34 -0
  47. package/dist/comprehension-quiz/providers/openai.js +53 -0
  48. package/dist/comprehension-quiz/question-generator.d.ts +69 -0
  49. package/dist/comprehension-quiz/question-generator.js +141 -0
  50. package/dist/comprehension-quiz/quiz-executor.d.ts +70 -0
  51. package/dist/comprehension-quiz/quiz-executor.js +165 -0
  52. package/dist/comprehension-quiz/types.d.ts +115 -0
  53. package/dist/comprehension-quiz/types.js +11 -0
  54. package/dist/core/archive.d.ts +14 -1
  55. package/dist/core/archive.js +1350 -190
  56. package/dist/core/artifact-graph/graph.d.ts +28 -9
  57. package/dist/core/artifact-graph/graph.js +94 -43
  58. package/dist/core/artifact-graph/index.d.ts +1 -1
  59. package/dist/core/artifact-graph/index.js +1 -1
  60. package/dist/core/artifact-graph/instruction-loader.d.ts +30 -3
  61. package/dist/core/artifact-graph/instruction-loader.js +70 -12
  62. package/dist/core/artifact-graph/outputs.d.ts +1 -0
  63. package/dist/core/artifact-graph/outputs.js +67 -5
  64. package/dist/core/artifact-graph/resolver.d.ts +14 -0
  65. package/dist/core/artifact-graph/resolver.js +69 -15
  66. package/dist/core/artifact-graph/types.js +21 -3
  67. package/dist/core/available-tools.d.ts +2 -2
  68. package/dist/core/available-tools.js +14 -3
  69. package/dist/core/change-metadata/schema.d.ts +2 -0
  70. package/dist/core/change-metadata/schema.js +13 -0
  71. package/dist/core/change-status-policy.d.ts +10 -1
  72. package/dist/core/change-status-policy.js +30 -2
  73. package/dist/core/command-generation/adapters/amazon-q.d.ts +4 -0
  74. package/dist/core/command-generation/adapters/amazon-q.js +11 -5
  75. package/dist/core/command-generation/adapters/antigravity.js +6 -5
  76. package/dist/core/command-generation/adapters/auggie.js +7 -6
  77. package/dist/core/command-generation/adapters/bob.d.ts +5 -1
  78. package/dist/core/command-generation/adapters/bob.js +11 -10
  79. package/dist/core/command-generation/adapters/claude.d.ts +1 -1
  80. package/dist/core/command-generation/adapters/claude.js +12 -17
  81. package/dist/core/command-generation/adapters/cline.js +5 -5
  82. package/dist/core/command-generation/adapters/codebuddy.js +8 -7
  83. package/dist/core/command-generation/adapters/continue.js +8 -7
  84. package/dist/core/command-generation/adapters/costrict.js +7 -6
  85. package/dist/core/command-generation/adapters/crush.js +9 -9
  86. package/dist/core/command-generation/adapters/cursor.js +8 -8
  87. package/dist/core/command-generation/adapters/devin.d.ts +19 -0
  88. package/dist/core/command-generation/adapters/devin.js +36 -0
  89. package/dist/core/command-generation/adapters/factory.js +7 -6
  90. package/dist/core/command-generation/adapters/gemini.js +40 -5
  91. package/dist/core/command-generation/adapters/github-copilot.js +6 -5
  92. package/dist/core/command-generation/adapters/iflow.js +9 -8
  93. package/dist/core/command-generation/adapters/index.d.ts +4 -2
  94. package/dist/core/command-generation/adapters/index.js +4 -2
  95. package/dist/core/command-generation/adapters/junie.js +6 -5
  96. package/dist/core/command-generation/adapters/kilocode.js +1 -1
  97. package/dist/core/command-generation/adapters/kiro.js +6 -5
  98. package/dist/core/command-generation/adapters/lingma.js +9 -9
  99. package/dist/core/command-generation/adapters/oh-my-pi.d.ts +21 -0
  100. package/dist/core/command-generation/adapters/oh-my-pi.js +42 -0
  101. package/dist/core/command-generation/adapters/opencode.js +6 -8
  102. package/dist/core/command-generation/adapters/pi.d.ts +2 -2
  103. package/dist/core/command-generation/adapters/pi.js +7 -10
  104. package/dist/core/command-generation/adapters/qoder.js +9 -9
  105. package/dist/core/command-generation/adapters/qwen.d.ts +7 -3
  106. package/dist/core/command-generation/adapters/qwen.js +14 -9
  107. package/dist/core/command-generation/adapters/roocode.d.ts +4 -4
  108. package/dist/core/command-generation/adapters/roocode.js +9 -9
  109. package/dist/core/command-generation/adapters/trae.d.ts +13 -0
  110. package/dist/core/command-generation/adapters/trae.js +28 -0
  111. package/dist/core/command-generation/adapters/zcode.d.ts +16 -0
  112. package/dist/core/command-generation/adapters/zcode.js +33 -0
  113. package/dist/core/command-generation/generator.d.ts +8 -0
  114. package/dist/core/command-generation/generator.js +15 -1
  115. package/dist/core/command-generation/index.d.ts +1 -1
  116. package/dist/core/command-generation/index.js +1 -1
  117. package/dist/core/command-generation/invocation.d.ts +73 -0
  118. package/dist/core/command-generation/invocation.js +77 -0
  119. package/dist/core/command-generation/registry.js +8 -4
  120. package/dist/core/command-generation/types.d.ts +9 -2
  121. package/dist/core/command-generation/yaml.d.ts +20 -6
  122. package/dist/core/command-generation/yaml.js +31 -21
  123. package/dist/core/command-surface.d.ts +15 -0
  124. package/dist/core/command-surface.js +33 -0
  125. package/dist/core/completions/command-registry.js +16 -61
  126. package/dist/core/completions/generators/bash-generator.js +41 -41
  127. package/dist/core/completions/generators/fish-generator.js +7 -7
  128. package/dist/core/completions/generators/powershell-generator.js +44 -37
  129. package/dist/core/completions/generators/zsh-generator.js +33 -33
  130. package/dist/core/completions/installers/zsh-installer.d.ts +9 -0
  131. package/dist/core/completions/installers/zsh-installer.js +20 -4
  132. package/dist/core/completions/templates/bash-templates.js +24 -24
  133. package/dist/core/completions/templates/fish-templates.js +38 -38
  134. package/dist/core/completions/templates/powershell-templates.js +28 -28
  135. package/dist/core/completions/templates/zsh-templates.js +39 -39
  136. package/dist/core/config-prompts.d.ts +1 -1
  137. package/dist/core/config-prompts.js +14 -1
  138. package/dist/core/config-schema.d.ts +10 -1
  139. package/dist/core/config-schema.js +67 -1
  140. package/dist/core/config.d.ts +15 -0
  141. package/dist/core/config.js +46 -5
  142. package/dist/core/file-state.js +56 -24
  143. package/dist/core/github-copilot/cloud-agent.d.ts +95 -0
  144. package/dist/core/github-copilot/cloud-agent.js +497 -0
  145. package/dist/core/global-config.d.ts +16 -0
  146. package/dist/core/init.d.ts +58 -0
  147. package/dist/core/init.js +474 -73
  148. package/dist/core/legacy-cleanup.d.ts +59 -0
  149. package/dist/core/legacy-cleanup.js +253 -24
  150. package/dist/core/list.js +23 -16
  151. package/dist/core/migration.d.ts +73 -1
  152. package/dist/core/migration.js +360 -11
  153. package/dist/core/modify/conflict-detector.d.ts +26 -0
  154. package/dist/core/modify/conflict-detector.js +62 -0
  155. package/dist/core/modify/dependency-propagator.d.ts +38 -0
  156. package/dist/core/modify/dependency-propagator.js +103 -0
  157. package/dist/core/modify/history-tracker.d.ts +34 -0
  158. package/dist/core/modify/history-tracker.js +114 -0
  159. package/dist/core/modify/index.d.ts +7 -0
  160. package/dist/core/modify/index.js +7 -0
  161. package/dist/core/onboarding-commands.d.ts +30 -0
  162. package/dist/core/onboarding-commands.js +38 -0
  163. package/dist/core/openspec-root.js +18 -15
  164. package/dist/core/parsers/change-parser.d.ts +17 -2
  165. package/dist/core/parsers/change-parser.js +35 -21
  166. package/dist/core/parsers/code-fence.d.ts +15 -0
  167. package/dist/core/parsers/code-fence.js +49 -0
  168. package/dist/core/parsers/markdown-parser.d.ts +0 -3
  169. package/dist/core/parsers/markdown-parser.js +7 -60
  170. package/dist/core/parsers/requirement-blocks.d.ts +29 -0
  171. package/dist/core/parsers/requirement-blocks.js +150 -31
  172. package/dist/core/parsers/requirement-text.d.ts +48 -0
  173. package/dist/core/parsers/requirement-text.js +98 -0
  174. package/dist/core/parsers/spec-structure.d.ts +1 -1
  175. package/dist/core/parsers/spec-structure.js +20 -30
  176. package/dist/core/profile-sync-drift.d.ts +0 -8
  177. package/dist/core/profile-sync-drift.js +49 -50
  178. package/dist/core/profiles.d.ts +2 -2
  179. package/dist/core/profiles.js +2 -2
  180. package/dist/core/project-config.d.ts +27 -18
  181. package/dist/core/project-config.js +101 -34
  182. package/dist/core/references.js +42 -4
  183. package/dist/core/relationship-health.d.ts +8 -0
  184. package/dist/core/relationship-health.js +13 -0
  185. package/dist/core/root-selection.d.ts +9 -6
  186. package/dist/core/root-selection.js +42 -5
  187. package/dist/core/schemas/base.schema.js +7 -2
  188. package/dist/core/shared/allowed-tools.d.ts +12 -0
  189. package/dist/core/shared/allowed-tools.js +12 -0
  190. package/dist/core/shared/index.d.ts +1 -0
  191. package/dist/core/shared/index.js +1 -0
  192. package/dist/core/shared/skill-content-equivalence.d.ts +7 -0
  193. package/dist/core/shared/skill-content-equivalence.js +41 -0
  194. package/dist/core/shared/skill-generation.js +17 -13
  195. package/dist/core/shared/skill-paths.d.ts +13 -0
  196. package/dist/core/shared/skill-paths.js +23 -0
  197. package/dist/core/shared/tool-detection.d.ts +27 -7
  198. package/dist/core/shared/tool-detection.js +167 -37
  199. package/dist/core/shared-skill-target.d.ts +16 -0
  200. package/dist/core/shared-skill-target.js +156 -0
  201. package/dist/core/specs-apply.d.ts +80 -33
  202. package/dist/core/specs-apply.js +667 -145
  203. package/dist/core/store/git.d.ts +13 -0
  204. package/dist/core/store/git.js +24 -0
  205. package/dist/core/store/operations.js +20 -0
  206. package/dist/core/templates/skill-templates.d.ts +3 -2
  207. package/dist/core/templates/skill-templates.js +3 -2
  208. package/dist/core/templates/workflows/apply-change.d.ts +10 -0
  209. package/dist/core/templates/workflows/apply-change.js +186 -323
  210. package/dist/core/templates/workflows/archive-change.js +387 -260
  211. package/dist/core/templates/workflows/bulk-archive-change.js +655 -475
  212. package/dist/core/templates/workflows/continue-change.js +210 -219
  213. package/dist/core/templates/workflows/explore.js +479 -443
  214. package/dist/core/templates/workflows/feedback.js +97 -97
  215. package/dist/core/templates/workflows/ff-change.js +200 -191
  216. package/dist/core/templates/workflows/modify-change.d.ts +4 -1
  217. package/dist/core/templates/workflows/modify-change.js +237 -115
  218. package/dist/core/templates/workflows/new-change.js +127 -134
  219. package/dist/core/templates/workflows/onboard.js +548 -542
  220. package/dist/core/templates/workflows/propose.js +273 -217
  221. package/dist/core/templates/workflows/store-selection.d.ts +1 -1
  222. package/dist/core/templates/workflows/store-selection.js +1 -1
  223. package/dist/core/templates/workflows/sync-specs.js +500 -273
  224. package/dist/core/templates/workflows/update-change.d.ts +10 -0
  225. package/dist/core/templates/workflows/update-change.js +177 -0
  226. package/dist/core/templates/workflows/verify-change.js +324 -326
  227. package/dist/core/update.d.ts +40 -5
  228. package/dist/core/update.js +411 -96
  229. package/dist/core/validation/constants.d.ts +4 -1
  230. package/dist/core/validation/constants.js +4 -1
  231. package/dist/core/validation/plan-validator.d.ts +8 -0
  232. package/dist/core/validation/plan-validator.js +45 -0
  233. package/dist/core/validation/task-numbering.d.ts +16 -0
  234. package/dist/core/validation/task-numbering.js +57 -0
  235. package/dist/core/validation/validator.d.ts +27 -3
  236. package/dist/core/validation/validator.js +337 -48
  237. package/dist/core/version-check.d.ts +152 -0
  238. package/dist/core/version-check.js +731 -0
  239. package/dist/core/view.js +13 -18
  240. package/dist/prompts/searchable-multi-select.js +1 -1
  241. package/dist/telemetry/caller-detection.d.ts +27 -0
  242. package/dist/telemetry/caller-detection.js +85 -0
  243. package/dist/telemetry/caller-detection.test.d.ts +5 -0
  244. package/dist/telemetry/config.d.ts +48 -2
  245. package/dist/telemetry/config.js +113 -11
  246. package/dist/telemetry/config.test.d.ts +5 -0
  247. package/dist/telemetry/deduplication.d.ts +35 -0
  248. package/dist/telemetry/deduplication.js +82 -0
  249. package/dist/telemetry/deduplication.test.d.ts +5 -0
  250. package/dist/telemetry/identity.d.ts +62 -22
  251. package/dist/telemetry/identity.js +147 -102
  252. package/dist/telemetry/index.d.ts +126 -15
  253. package/dist/telemetry/index.js +569 -37
  254. package/dist/telemetry/sanitization.d.ts +40 -0
  255. package/dist/telemetry/sanitization.js +114 -0
  256. package/dist/telemetry/sanitization.test.d.ts +5 -0
  257. package/dist/telemetry/throttling.d.ts +20 -0
  258. package/dist/telemetry/throttling.js +70 -0
  259. package/dist/ui/welcome-screen.d.ts +9 -1
  260. package/dist/ui/welcome-screen.js +91 -38
  261. package/dist/utils/change-metadata.d.ts +43 -0
  262. package/dist/utils/change-metadata.js +123 -7
  263. package/dist/utils/change-utils.d.ts +10 -4
  264. package/dist/utils/change-utils.js +20 -13
  265. package/dist/utils/ci.d.ts +12 -0
  266. package/dist/utils/ci.js +16 -0
  267. package/dist/utils/command-references.d.ts +92 -6
  268. package/dist/utils/command-references.js +180 -7
  269. package/dist/utils/date.d.ts +8 -0
  270. package/dist/utils/date.js +13 -0
  271. package/dist/utils/file-system.d.ts +10 -0
  272. package/dist/utils/file-system.js +70 -0
  273. package/dist/utils/index.d.ts +1 -1
  274. package/dist/utils/index.js +1 -1
  275. package/dist/utils/interactive.d.ts +23 -0
  276. package/dist/utils/interactive.js +32 -0
  277. package/dist/utils/item-discovery.d.ts +19 -0
  278. package/dist/utils/item-discovery.js +30 -48
  279. package/dist/utils/shell-detection.d.ts +1 -1
  280. package/dist/utils/shell-detection.js +64 -11
  281. package/dist/utils/spec-discovery.d.ts +40 -0
  282. package/dist/utils/spec-discovery.js +115 -0
  283. package/dist/utils/task-progress.d.ts +29 -1
  284. package/dist/utils/task-progress.js +109 -15
  285. package/package.json +96 -84
  286. package/schemas/spec-driven/schema.yaml +252 -184
  287. package/schemas/spec-driven/templates/design.md +19 -19
  288. package/schemas/spec-driven/templates/plan-template.md +91 -0
  289. package/schemas/spec-driven/templates/proposal.md +29 -24
  290. package/schemas/spec-driven/templates/spec.md +11 -8
  291. package/schemas/spec-driven/templates/tasks.md +9 -9
  292. package/scripts/postinstall.js +83 -83
  293. package/dist/core/command-generation/adapters/codex.d.ts +0 -16
  294. package/dist/core/command-generation/adapters/codex.js +0 -39
  295. package/dist/core/command-generation/adapters/windsurf.d.ts +0 -14
  296. package/dist/core/command-generation/adapters/windsurf.js +0 -38
  297. package/dist/core/comprehension/config.d.ts +0 -20
  298. package/dist/core/comprehension/config.js +0 -23
  299. package/dist/core/comprehension/fingerprint.d.ts +0 -14
  300. package/dist/core/comprehension/fingerprint.js +0 -33
  301. package/dist/core/comprehension/index.d.ts +0 -57
  302. package/dist/core/comprehension/index.js +0 -87
  303. package/dist/core/comprehension/pass-record.d.ts +0 -29
  304. package/dist/core/comprehension/pass-record.js +0 -64
  305. package/dist/core/comprehension/stats.d.ts +0 -35
  306. package/dist/core/comprehension/stats.js +0 -133
  307. package/dist/core/templates/workflows/comprehension-guidance.d.ts +0 -9
  308. package/dist/core/templates/workflows/comprehension-guidance.js +0 -71
  309. package/dist/core/templates/workflows/mcp-guidance.d.ts +0 -13
  310. package/dist/core/templates/workflows/mcp-guidance.js +0 -131
  311. package/dist/core/templates/workflows/user-prompt-guidance.d.ts +0 -16
  312. package/dist/core/templates/workflows/user-prompt-guidance.js +0 -48
  313. package/dist/telemetry/caller.d.ts +0 -5
  314. package/dist/telemetry/caller.js +0 -29
  315. package/dist/telemetry/client.d.ts +0 -27
  316. package/dist/telemetry/client.js +0 -127
  317. package/dist/telemetry/command-context.d.ts +0 -13
  318. package/dist/telemetry/command-context.js +0 -59
  319. package/dist/telemetry/comprehension.d.ts +0 -44
  320. package/dist/telemetry/comprehension.js +0 -105
  321. package/dist/telemetry/content.d.ts +0 -10
  322. package/dist/telemetry/content.js +0 -56
  323. package/dist/telemetry/git-stats.d.ts +0 -12
  324. package/dist/telemetry/git-stats.js +0 -69
  325. package/dist/telemetry/identify-cache.d.ts +0 -7
  326. package/dist/telemetry/identify-cache.js +0 -47
  327. package/dist/telemetry/input.d.ts +0 -17
  328. package/dist/telemetry/input.js +0 -68
  329. package/dist/telemetry/marker.d.ts +0 -37
  330. package/dist/telemetry/marker.js +0 -67
  331. package/dist/telemetry/workflow.d.ts +0 -85
  332. package/dist/telemetry/workflow.js +0 -318
  333. package/schemas/spec-driven/templates/plan.md +0 -19
@@ -2,44 +2,44 @@
2
2
  * Static template strings for Zsh completion scripts.
3
3
  * These are Zsh-specific helper functions that never change.
4
4
  */
5
- export const ZSH_DYNAMIC_HELPERS = `# Dynamic completion helpers
6
-
7
- # Use openspec __complete to get available changes
8
- _openspec_complete_changes() {
9
- local -a changes
10
- while IFS=$'\\t' read -r id desc; do
11
- changes+=("$id:$desc")
12
- done < <(openspec __complete changes 2>/dev/null)
13
- _describe "change" changes
14
- }
15
-
16
- # Use openspec __complete to get available specs
17
- _openspec_complete_specs() {
18
- local -a specs
19
- while IFS=$'\\t' read -r id desc; do
20
- specs+=("$id:$desc")
21
- done < <(openspec __complete specs 2>/dev/null)
22
- _describe "spec" specs
23
- }
24
-
25
- # Get both changes and specs
26
- _openspec_complete_items() {
27
- local -a items
28
- while IFS=$'\\t' read -r id desc; do
29
- items+=("$id:$desc")
30
- done < <(openspec __complete changes 2>/dev/null)
31
- while IFS=$'\\t' read -r id desc; do
32
- items+=("$id:$desc")
33
- done < <(openspec __complete specs 2>/dev/null)
34
- _describe "item" items
35
- }
36
-
37
- # Use openspec __complete to get available schemas
38
- _openspec_complete_schemas() {
39
- local -a schemas
40
- while IFS=$'\\t' read -r id desc; do
41
- schemas+=("$id:$desc")
42
- done < <(openspec __complete schemas 2>/dev/null)
43
- _describe "schema" schemas
5
+ export const ZSH_DYNAMIC_HELPERS = `# Dynamic completion helpers
6
+
7
+ # Use openspec __complete to get available changes
8
+ _openspec_complete_changes() {
9
+ local -a changes
10
+ while IFS=$'\\t' read -r id desc; do
11
+ changes+=("$id:$desc")
12
+ done < <(openspec __complete changes 2>/dev/null)
13
+ _describe "change" changes
14
+ }
15
+
16
+ # Use openspec __complete to get available specs
17
+ _openspec_complete_specs() {
18
+ local -a specs
19
+ while IFS=$'\\t' read -r id desc; do
20
+ specs+=("$id:$desc")
21
+ done < <(openspec __complete specs 2>/dev/null)
22
+ _describe "spec" specs
23
+ }
24
+
25
+ # Get both changes and specs
26
+ _openspec_complete_items() {
27
+ local -a items
28
+ while IFS=$'\\t' read -r id desc; do
29
+ items+=("$id:$desc")
30
+ done < <(openspec __complete changes 2>/dev/null)
31
+ while IFS=$'\\t' read -r id desc; do
32
+ items+=("$id:$desc")
33
+ done < <(openspec __complete specs 2>/dev/null)
34
+ _describe "item" items
35
+ }
36
+
37
+ # Use openspec __complete to get available schemas
38
+ _openspec_complete_schemas() {
39
+ local -a schemas
40
+ while IFS=$'\\t' read -r id desc; do
41
+ schemas+=("$id:$desc")
42
+ done < <(openspec __complete schemas 2>/dev/null)
43
+ _describe "schema" schemas
44
44
  }`;
45
45
  //# sourceMappingURL=zsh-templates.js.map
@@ -2,7 +2,7 @@ import type { ProjectConfig } from './project-config.js';
2
2
  /**
3
3
  * Serialize config to YAML string with helpful comments.
4
4
  *
5
- * @param config - Partial config object (schema required, context/rules optional)
5
+ * @param config - Partial config object (schema required, other fields optional)
6
6
  * @returns YAML string ready to write to file
7
7
  */
8
8
  export declare function serializeConfig(config: Partial<ProjectConfig>): string;
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Serialize config to YAML string with helpful comments.
3
3
  *
4
- * @param config - Partial config object (schema required, context/rules optional)
4
+ * @param config - Partial config object (schema required, other fields optional)
5
5
  * @returns YAML string ready to write to file
6
6
  */
7
7
  export function serializeConfig(config) {
@@ -29,6 +29,19 @@ export function serializeConfig(config) {
29
29
  lines.push('# - Always include a "Non-goals" section');
30
30
  lines.push('# tasks:');
31
31
  lines.push('# - Break tasks into chunks of max 2 hours');
32
+ lines.push('');
33
+ // Operation guidance section with comments
34
+ lines.push('# Per-operation guidance (optional)');
35
+ lines.push('# Add advisory guidance for how apply and archive work should be conducted.');
36
+ lines.push('# This is separate from artifact rules above.');
37
+ lines.push('# Example:');
38
+ lines.push('# operations:');
39
+ lines.push('# apply:');
40
+ lines.push('# guidance:');
41
+ lines.push('# - Keep test summaries concise');
42
+ lines.push('# archive:');
43
+ lines.push('# guidance:');
44
+ lines.push('# - Summarize the archive outcome before finishing');
32
45
  return lines.join('\n') + '\n';
33
46
  }
34
47
  //# sourceMappingURL=config-prompts.js.map
@@ -11,16 +11,25 @@ export declare const GlobalConfigSchema: z.ZodObject<{
11
11
  }>>>;
12
12
  delivery: z.ZodDefault<z.ZodOptional<z.ZodEnum<{
13
13
  commands: "commands";
14
- skills: "skills";
15
14
  both: "both";
15
+ skills: "skills";
16
16
  }>>>;
17
17
  workflows: z.ZodOptional<z.ZodArray<z.ZodString>>;
18
+ defaultStore: z.ZodOptional<z.ZodString>;
19
+ telemetry: z.ZodOptional<z.ZodObject<{
20
+ enabled: z.ZodOptional<z.ZodBoolean>;
21
+ }, z.core.$loose>>;
18
22
  }, z.core.$loose>;
19
23
  export type GlobalConfigType = z.infer<typeof GlobalConfigSchema>;
20
24
  /**
21
25
  * Default configuration values.
22
26
  */
23
27
  export declare const DEFAULT_CONFIG: GlobalConfigType;
28
+ /**
29
+ * True when a dot-notation key path contains a prototype-reaching segment.
30
+ * Callers that bypass key validation (e.g. --allow-unknown) still must not bypass this.
31
+ */
32
+ export declare function hasUnsafeKeySegment(path: string): boolean;
24
33
  /**
25
34
  * Validate a config key path for CLI set operations.
26
35
  * Unknown top-level keys are rejected unless explicitly allowed by the caller.
@@ -20,6 +20,18 @@ export const GlobalConfigSchema = z
20
20
  workflows: z
21
21
  .array(z.string())
22
22
  .optional(),
23
+ defaultStore: z
24
+ .string()
25
+ .optional()
26
+ .describe('Store id used as fallback root when no explicit --store, local root, or project-level store: pointer resolves'),
27
+ // passthrough keeps runtime-managed fields (anonymousId, noticeSeen) valid
28
+ // under CLI validate when users only set telemetry.enabled.
29
+ telemetry: z
30
+ .object({
31
+ enabled: z.boolean().optional(),
32
+ })
33
+ .passthrough()
34
+ .optional(),
23
35
  })
24
36
  .passthrough();
25
37
  /**
@@ -30,7 +42,29 @@ export const DEFAULT_CONFIG = {
30
42
  profile: 'core',
31
43
  delivery: 'both',
32
44
  };
33
- const KNOWN_TOP_LEVEL_KEYS = new Set([...Object.keys(DEFAULT_CONFIG), 'workflows']);
45
+ const KNOWN_TOP_LEVEL_KEYS = new Set([
46
+ ...Object.keys(DEFAULT_CONFIG),
47
+ 'workflows',
48
+ 'defaultStore',
49
+ 'telemetry',
50
+ ]);
51
+ /** Nested keys users may set under `telemetry` via the CLI. */
52
+ const TELEMETRY_SETTABLE_KEYS = new Set(['enabled']);
53
+ /**
54
+ * Key segments that would reach the prototype chain instead of the config object.
55
+ * Never valid as configuration keys, so rejecting them costs nothing.
56
+ */
57
+ const UNSAFE_KEY_SEGMENTS = new Set(['__proto__', 'constructor', 'prototype']);
58
+ function hasUnsafeSegment(keys) {
59
+ return keys.some((key) => UNSAFE_KEY_SEGMENTS.has(key));
60
+ }
61
+ /**
62
+ * True when a dot-notation key path contains a prototype-reaching segment.
63
+ * Callers that bypass key validation (e.g. --allow-unknown) still must not bypass this.
64
+ */
65
+ export function hasUnsafeKeySegment(path) {
66
+ return hasUnsafeSegment(path.split('.'));
67
+ }
34
68
  /**
35
69
  * Validate a config key path for CLI set operations.
36
70
  * Unknown top-level keys are rejected unless explicitly allowed by the caller.
@@ -40,6 +74,10 @@ export function validateConfigKeyPath(path) {
40
74
  if (rawKeys.length === 0 || rawKeys.some((key) => key.trim() === '')) {
41
75
  return { valid: false, reason: 'Key path must not be empty' };
42
76
  }
77
+ const unsafeKey = rawKeys.find((key) => UNSAFE_KEY_SEGMENTS.has(key));
78
+ if (unsafeKey) {
79
+ return { valid: false, reason: `Key segment "${unsafeKey}" is not allowed` };
80
+ }
43
81
  const rootKey = rawKeys[0];
44
82
  if (!KNOWN_TOP_LEVEL_KEYS.has(rootKey)) {
45
83
  return { valid: false, reason: `Unknown top-level key "${rootKey}"` };
@@ -50,6 +88,18 @@ export function validateConfigKeyPath(path) {
50
88
  }
51
89
  return { valid: true };
52
90
  }
91
+ if (rootKey === 'telemetry') {
92
+ if (rawKeys.length === 1) {
93
+ return { valid: false, reason: 'Set nested keys under telemetry (e.g. telemetry.enabled)' };
94
+ }
95
+ if (rawKeys.length !== 2 || !TELEMETRY_SETTABLE_KEYS.has(rawKeys[1])) {
96
+ return {
97
+ valid: false,
98
+ reason: `Unknown telemetry key "${rawKeys.slice(1).join('.')}" (allowed: enabled)`,
99
+ };
100
+ }
101
+ return { valid: true };
102
+ }
53
103
  if (rawKeys.length > 1) {
54
104
  return { valid: false, reason: `"${rootKey}" does not support nested keys` };
55
105
  }
@@ -64,6 +114,9 @@ export function validateConfigKeyPath(path) {
64
114
  */
65
115
  export function getNestedValue(obj, path) {
66
116
  const keys = path.split('.');
117
+ if (hasUnsafeSegment(keys)) {
118
+ return undefined;
119
+ }
67
120
  let current = obj;
68
121
  for (const key of keys) {
69
122
  if (current === null || current === undefined) {
@@ -86,6 +139,14 @@ export function getNestedValue(obj, path) {
86
139
  */
87
140
  export function setNestedValue(obj, path, value) {
88
141
  const keys = path.split('.');
142
+ // Compared literally rather than through a helper, so the guard is plain to a
143
+ // reader and to static analysis. Checked for the whole path before anything is
144
+ // written, so a rejected key never leaves half-created objects behind.
145
+ for (const key of keys) {
146
+ if (key === '__proto__' || key === 'constructor' || key === 'prototype') {
147
+ return;
148
+ }
149
+ }
89
150
  let current = obj;
90
151
  for (let i = 0; i < keys.length - 1; i++) {
91
152
  const key = keys[i];
@@ -106,6 +167,11 @@ export function setNestedValue(obj, path, value) {
106
167
  */
107
168
  export function deleteNestedValue(obj, path) {
108
169
  const keys = path.split('.');
170
+ for (const key of keys) {
171
+ if (key === '__proto__' || key === 'constructor' || key === 'prototype') {
172
+ return false;
173
+ }
174
+ }
109
175
  let current = obj;
110
176
  for (let i = 0; i < keys.length - 1; i++) {
111
177
  const key = keys[i];
@@ -1,4 +1,5 @@
1
1
  export declare const OPENSPEC_DIR_NAME = "openspec";
2
+ export declare const OPENSPEC_SKILL_NAMES: readonly ["openspec-explore", "openspec-new-change", "openspec-continue-change", "openspec-apply-change", "openspec-update-change", "openspec-ff-change", "openspec-sync-specs", "openspec-archive-change", "openspec-bulk-archive-change", "openspec-verify-change", "openspec-onboard", "openspec-propose"];
2
3
  export declare const OPENSPEC_MARKERS: {
3
4
  start: string;
4
5
  end: string;
@@ -12,7 +13,21 @@ export interface AIToolOption {
12
13
  available: boolean;
13
14
  successLabel?: string;
14
15
  skillsDir?: string;
16
+ legacySkillsDirs?: string[];
17
+ globalSkillsDir?: string;
15
18
  detectionPaths?: string[];
19
+ setupNote?: string;
16
20
  }
17
21
  export declare const AI_TOOLS: AIToolOption[];
22
+ /**
23
+ * Retired tool ids that still resolve, so a rebrand does not break scripted
24
+ * `--tools` invocations. Windsurf was rebranded to Devin Desktop on
25
+ * 2026-06-02 and its config directory moved from `.windsurf/` to `.devin/`;
26
+ * `--tools windsurf` therefore configures `devin`.
27
+ */
28
+ export declare const TOOL_ID_ALIASES: Record<string, string>;
29
+ /**
30
+ * Resolves a tool id through TOOL_ID_ALIASES, leaving current ids untouched.
31
+ */
32
+ export declare function resolveToolIdAlias(toolId: string): string;
18
33
  //# sourceMappingURL=config.d.ts.map
@@ -1,4 +1,18 @@
1
1
  export const OPENSPEC_DIR_NAME = 'openspec';
2
+ export const OPENSPEC_SKILL_NAMES = [
3
+ 'openspec-explore',
4
+ 'openspec-new-change',
5
+ 'openspec-continue-change',
6
+ 'openspec-apply-change',
7
+ 'openspec-update-change',
8
+ 'openspec-ff-change',
9
+ 'openspec-sync-specs',
10
+ 'openspec-archive-change',
11
+ 'openspec-bulk-archive-change',
12
+ 'openspec-verify-change',
13
+ 'openspec-onboard',
14
+ 'openspec-propose',
15
+ ];
2
16
  export const OPENSPEC_MARKERS = {
3
17
  start: '<!-- OPENSPEC:START -->',
4
18
  end: '<!-- OPENSPEC:END -->'
@@ -10,7 +24,9 @@ export const AI_TOOLS = [
10
24
  { name: 'Bob Shell', value: 'bob', available: true, successLabel: 'Bob Shell', skillsDir: '.bob' },
11
25
  { name: 'Claude Code', value: 'claude', available: true, successLabel: 'Claude Code', skillsDir: '.claude' },
12
26
  { name: 'Cline', value: 'cline', available: true, successLabel: 'Cline', skillsDir: '.cline' },
13
- { name: 'Codex', value: 'codex', available: true, successLabel: 'Codex', skillsDir: '.codex' },
27
+ { name: 'CodeArts', value: 'codeartsagent', available: true, successLabel: 'CodeArts', skillsDir: '.codeartsdoer' },
28
+ { name: 'Codex', value: 'codex', available: true, successLabel: 'Codex', skillsDir: '.agents', legacySkillsDirs: ['.codex'], detectionPaths: ['.agents/skills', '.codex/skills'] },
29
+ { name: 'Devin Desktop (formerly Windsurf)', value: 'devin', available: true, successLabel: 'Devin Desktop', skillsDir: '.devin', detectionPaths: ['.devin', '.windsurf'] },
14
30
  { name: 'ForgeCode', value: 'forgecode', available: true, successLabel: 'ForgeCode', skillsDir: '.forge' },
15
31
  { name: 'CodeBuddy Code (CLI)', value: 'codebuddy', available: true, successLabel: 'CodeBuddy Code', skillsDir: '.codebuddy' },
16
32
  { name: 'Continue', value: 'continue', available: true, successLabel: 'Continue (VS Code / JetBrains / Cli)', skillsDir: '.continue' },
@@ -20,20 +36,45 @@ export const AI_TOOLS = [
20
36
  { name: 'Factory Droid', value: 'factory', available: true, successLabel: 'Factory Droid', skillsDir: '.factory' },
21
37
  { name: 'Gemini CLI', value: 'gemini', available: true, successLabel: 'Gemini CLI', skillsDir: '.gemini' },
22
38
  { name: 'GitHub Copilot', value: 'github-copilot', available: true, successLabel: 'GitHub Copilot', skillsDir: '.github', detectionPaths: ['.github/copilot-instructions.md', '.github/instructions', '.github/workflows/copilot-setup-steps.yml', '.github/prompts', '.github/agents', '.github/skills', '.github/.mcp.json'] },
39
+ { name: 'Hermes Agent', value: 'hermes', available: true, successLabel: 'Hermes Agent', skillsDir: '.hermes', detectionPaths: ['.hermes', 'HERMES.md', '.hermes.md'], setupNote: "Hermes only loads skills from ~/.hermes/skills by default. Add this project's .hermes/skills directory to skills.external_dirs in ~/.hermes/config.yaml so Hermes picks up the generated OpenSpec skills." },
23
40
  { name: 'iFlow', value: 'iflow', available: true, successLabel: 'iFlow', skillsDir: '.iflow' },
24
41
  { name: 'Junie', value: 'junie', available: true, successLabel: 'Junie', skillsDir: '.junie' },
25
42
  { name: 'Kilo Code', value: 'kilocode', available: true, successLabel: 'Kilo Code', skillsDir: '.kilocode' },
26
- { name: 'Kimi CLI', value: 'kimi', available: true, successLabel: 'Kimi CLI', skillsDir: '.kimi' },
43
+ { name: 'Kimi Code', value: 'kimi', available: true, successLabel: 'Kimi Code', skillsDir: '.kimi-code', detectionPaths: ['.kimi-code', '.kimi'] },
27
44
  { name: 'Kiro', value: 'kiro', available: true, successLabel: 'Kiro', skillsDir: '.kiro' },
28
45
  { name: 'Lingma', value: 'lingma', available: true, successLabel: 'Lingma', skillsDir: '.lingma' },
46
+ { name: 'MiniMax Code', value: 'minimax-code', available: true, successLabel: 'MiniMax Code', globalSkillsDir: '.minimax' },
29
47
  { name: 'Mistral Vibe', value: 'vibe', available: true, successLabel: 'Mistral Vibe', skillsDir: '.vibe' },
48
+ { name: 'Oh My Pi', value: 'oh-my-pi', available: true, successLabel: 'Oh My Pi', skillsDir: '.omp' },
30
49
  { name: 'OpenCode', value: 'opencode', available: true, successLabel: 'OpenCode', skillsDir: '.opencode' },
31
50
  { name: 'Pi', value: 'pi', available: true, successLabel: 'Pi', skillsDir: '.pi' },
32
51
  { name: 'Qoder', value: 'qoder', available: true, successLabel: 'Qoder', skillsDir: '.qoder' },
33
52
  { name: 'Qwen Code', value: 'qwen', available: true, successLabel: 'Qwen Code', skillsDir: '.qwen' },
34
- { name: 'RooCode', value: 'roocode', available: true, successLabel: 'RooCode', skillsDir: '.roo' },
53
+ { name: 'Rovo Dev CLI', value: 'rovodev', available: true, successLabel: 'Rovo Dev CLI', skillsDir: '.rovodev', detectionPaths: ['.rovodev/skills', '.rovodev'] },
54
+ { name: 'Zoo Code', value: 'roocode', available: true, successLabel: 'Zoo Code', skillsDir: '.roo' },
35
55
  { name: 'Trae', value: 'trae', available: true, successLabel: 'Trae', skillsDir: '.trae' },
36
- { name: 'Windsurf', value: 'windsurf', available: true, successLabel: 'Windsurf', skillsDir: '.windsurf' },
37
- { name: 'AGENTS.md (works with Amp, VS Code, …)', value: 'agents', available: false, successLabel: 'your AGENTS.md-compatible assistant' }
56
+ { name: 'ZCode', value: 'zcode', available: true, successLabel: 'ZCode', skillsDir: '.zcode' },
57
+ // Vendor-neutral target for assistants that read the shared `.agents` root.
58
+ // Detection keys off `.agents/skills` rather than the bare root: frameworks use
59
+ // `.agents/` for more than skills, so the root alone says nothing about skills.
60
+ // A project that does keep skills there is a project this target fits, the same
61
+ // way `.claude/` selects Claude Code — the signal is the user's setup, not
62
+ // OpenSpec's own files.
63
+ { name: 'Shared .agents skills', value: 'agents', available: true, successLabel: 'shared .agents skills', skillsDir: '.agents', detectionPaths: ['.agents/skills'] }
38
64
  ];
65
+ /**
66
+ * Retired tool ids that still resolve, so a rebrand does not break scripted
67
+ * `--tools` invocations. Windsurf was rebranded to Devin Desktop on
68
+ * 2026-06-02 and its config directory moved from `.windsurf/` to `.devin/`;
69
+ * `--tools windsurf` therefore configures `devin`.
70
+ */
71
+ export const TOOL_ID_ALIASES = {
72
+ windsurf: 'devin',
73
+ };
74
+ /**
75
+ * Resolves a tool id through TOOL_ID_ALIASES, leaving current ids untouched.
76
+ */
77
+ export function resolveToolIdAlias(toolId) {
78
+ return TOOL_ID_ALIASES[toolId] ?? toolId;
79
+ }
39
80
  //# sourceMappingURL=config.js.map
@@ -1,5 +1,6 @@
1
1
  import * as nodeFs from 'node:fs';
2
2
  import * as path from 'node:path';
3
+ import { randomUUID } from 'node:crypto';
3
4
  import { FileSystemUtils } from '../utils/file-system.js';
4
5
  import { StoreError } from './store/errors.js';
5
6
  const fs = nodeFs.promises;
@@ -19,9 +20,15 @@ export function makeLockErrorFactory(data) {
19
20
  });
20
21
  };
21
22
  }
22
- const STALE_LOCK_THRESHOLD_MS = 30_000;
23
23
  const LOCK_DEADLINE_MS = 5000;
24
24
  const LOCK_POLL_MS = 25;
25
+ const PRIVATE_FILE_MODE = 0o600;
26
+ const lockOwnership = new WeakMap();
27
+ function isUnsupportedSyncError(error) {
28
+ return (isNodeErrorCode(error, 'EINVAL') ||
29
+ isNodeErrorCode(error, 'ENOTSUP') ||
30
+ isNodeErrorCode(error, 'ENOSYS'));
31
+ }
25
32
  export function isNodeErrorCode(error, code) {
26
33
  return (typeof error === 'object' &&
27
34
  error !== null &&
@@ -56,7 +63,10 @@ export async function writeFileAtomically(filePath, content) {
56
63
  await FileSystemUtils.createDirectory(dirPath);
57
64
  const tempPath = path.join(dirPath, `.${path.basename(filePath)}.${process.pid}.${Date.now()}.${Math.random().toString(36).slice(2)}.tmp`);
58
65
  try {
59
- await fs.writeFile(tempPath, content, 'utf-8');
66
+ await fs.writeFile(tempPath, content, {
67
+ encoding: 'utf-8',
68
+ mode: PRIVATE_FILE_MODE,
69
+ });
60
70
  await fs.rename(tempPath, filePath);
61
71
  }
62
72
  catch (error) {
@@ -74,39 +84,61 @@ export async function acquireFileLock(options) {
74
84
  const deadline = Date.now() + LOCK_DEADLINE_MS;
75
85
  while (true) {
76
86
  try {
77
- return await fs.open(lockPath, 'wx');
87
+ const lock = await fs.open(lockPath, 'wx', PRIVATE_FILE_MODE);
88
+ const ownershipToken = `${process.pid}:${randomUUID()}`;
89
+ try {
90
+ await lock.writeFile(ownershipToken, 'utf-8');
91
+ try {
92
+ await lock.sync();
93
+ }
94
+ catch (error) {
95
+ // Some FUSE and network filesystems support exclusive lock files but
96
+ // explicitly do not implement fsync. The token is still visible to
97
+ // cooperating processes, so do not make those projects unusable.
98
+ if (!isUnsupportedSyncError(error)) {
99
+ throw error;
100
+ }
101
+ }
102
+ }
103
+ catch (error) {
104
+ await lock.close().catch(() => undefined);
105
+ await fs.rm(lockPath, { force: true }).catch(() => undefined);
106
+ throw error;
107
+ }
108
+ lockOwnership.set(lock, ownershipToken);
109
+ return lock;
78
110
  }
79
111
  catch (error) {
80
112
  if (!isNodeErrorCode(error, 'EEXIST')) {
81
113
  // A permission or filesystem problem, not contention - say so.
82
114
  throw errorFor('create-failed', { lockPath, cause: error });
83
115
  }
84
- // A crashed process leaves the lock behind forever; state-file
85
- // writes are sub-second, so an old lock is an orphan - steal it.
86
- let staleStolen = false;
87
- try {
88
- const lockStat = await fs.stat(lockPath);
89
- if (Date.now() - lockStat.mtimeMs > STALE_LOCK_THRESHOLD_MS) {
90
- await fs.rm(lockPath, { force: true });
91
- staleStolen = true;
92
- }
93
- }
94
- catch {
95
- // The holder released between open and stat - retry, but stay
96
- // bounded: a persistently failing stat (EPERM, delete-pending)
97
- // must hit the deadline instead of spinning forever.
98
- }
99
- if (!staleStolen) {
100
- if (Date.now() >= deadline) {
101
- throw errorFor('timeout', { lockPath });
102
- }
103
- await sleep(LOCK_POLL_MS);
116
+ // Never steal by age: unlinking a supposedly stale path can race with
117
+ // its replacement and erase a live owner's lock. The timeout diagnostic
118
+ // gives the user an explicit recovery path for genuinely orphaned locks.
119
+ if (Date.now() >= deadline) {
120
+ throw errorFor('timeout', { lockPath });
104
121
  }
122
+ await sleep(LOCK_POLL_MS);
105
123
  }
106
124
  }
107
125
  }
108
126
  export async function releaseFileLock(lock, lockPath) {
127
+ const ownershipToken = lockOwnership.get(lock);
128
+ lockOwnership.delete(lock);
109
129
  await lock.close().catch(() => undefined);
110
- await fs.rm(lockPath, { force: true }).catch(() => undefined);
130
+ if (ownershipToken === undefined) {
131
+ return;
132
+ }
133
+ try {
134
+ const currentToken = await fs.readFile(lockPath, 'utf-8');
135
+ if (currentToken === ownershipToken) {
136
+ await fs.rm(lockPath, { force: true });
137
+ }
138
+ }
139
+ catch {
140
+ // The lock was already removed or replaced with an unreadable path.
141
+ // In either case, this owner must not remove anything else.
142
+ }
111
143
  }
112
144
  //# sourceMappingURL=file-state.js.map
@@ -0,0 +1,95 @@
1
+ /**
2
+ * GitHub Copilot Cloud Agent Support
3
+ *
4
+ * Generates copilot-setup-steps.yml and .github/agents/openspec.agent.md
5
+ * when the github-copilot tool is selected during init/update.
6
+ * These files enable the GitHub Copilot coding agent (cloud) to use the
7
+ * OpenSpec CLI in its ephemeral dev environment.
8
+ */
9
+ /**
10
+ * Check if a tool list includes github-copilot.
11
+ */
12
+ export declare function includesGitHubCopilot(toolIds: string[]): boolean;
13
+ /**
14
+ * Generate the copilot-setup-steps.yml workflow file content.
15
+ * This workflow pre-installs the OpenSpec CLI in the Copilot coding agent's
16
+ * ephemeral GitHub Actions environment.
17
+ */
18
+ export declare function generateCopilotSetupSteps(): string;
19
+ /**
20
+ * Generate the .github/agents/openspec.agent.md custom agent file content.
21
+ * This tells the GitHub Copilot coding agent how to use the OpenSpec CLI.
22
+ */
23
+ export declare function generateCopilotAgentFile(): string;
24
+ /**
25
+ * File paths (relative to project root) for the generated files.
26
+ */
27
+ export declare const COPILOT_CLOUD_FILES: {
28
+ readonly setupSteps: string;
29
+ readonly agent: string;
30
+ };
31
+ /**
32
+ * Reconcile Copilot cloud agent files in the project directory.
33
+ * Creates missing files and refreshes recognized legacy generated files while
34
+ * preserving current generated content and user customizations.
35
+ *
36
+ * @returns Object indicating which files were written.
37
+ */
38
+ export declare function writeCopilotCloudFiles(projectPath: string): Promise<{
39
+ setupStepsWritten: boolean;
40
+ agentWritten: boolean;
41
+ }>;
42
+ /**
43
+ * Remove copilot cloud agent files from the project directory.
44
+ * Used when github-copilot is deselected.
45
+ *
46
+ * @returns Number of files removed.
47
+ */
48
+ export declare function removeCopilotCloudFiles(projectPath: string): Promise<number>;
49
+ /**
50
+ * Read the persisted opt-in for Copilot cloud-file generation.
51
+ *
52
+ * Tri-state: `true` (opted in), `false` (explicitly opted out), or `undefined`
53
+ * (never decided). A malformed value is treated as undecided rather than an
54
+ * error, matching how {@link readProjectConfig} degrades on bad fields.
55
+ */
56
+ export declare function readCopilotCloudOptIn(projectPath: string): boolean | undefined;
57
+ /**
58
+ * True when a managed Copilot cloud file (the current generation or a
59
+ * recognized legacy one) already exists. Projects created before the opt-in
60
+ * prompt existed are treated as implicitly opted in, so `openspec update`
61
+ * keeps their files current instead of silently abandoning them.
62
+ */
63
+ export declare function hasExistingManagedCloudFiles(projectPath: string): Promise<boolean>;
64
+ /**
65
+ * Effective decision on whether to generate/refresh Copilot cloud files.
66
+ * An explicit opt-in or opt-out always wins; when undecided, fall back to
67
+ * whether managed files already exist (the migration path above).
68
+ */
69
+ export declare function isCopilotCloudEnabled(projectPath: string): Promise<boolean>;
70
+ /**
71
+ * Persist the Copilot cloud opt-in into openspec/config.yaml.
72
+ *
73
+ * Uses the YAML document model rather than a re-serialize so the user's
74
+ * existing comments, ordering, and formatting survive untouched — the config
75
+ * file is hand-authored and heavily commented, so a lossy round-trip would be
76
+ * its own source of toil. No-op when no config file exists yet (init creates it
77
+ * before this is called); the caller treats persistence failures as non-fatal.
78
+ */
79
+ export declare function persistCopilotCloudOptIn(projectPath: string, value: boolean): Promise<void>;
80
+ /**
81
+ * Return the managed cloud-file paths (relative to the project root) that
82
+ * currently hold user-owned, non-managed content — i.e. files OpenSpec will
83
+ * deliberately leave untouched. Used to tell an opted-in user that we preserved
84
+ * their existing file rather than silently doing nothing, which is the honest
85
+ * answer to "will this affect my existing Copilot cloud setup?".
86
+ */
87
+ export declare function findUnmanagedCloudFiles(projectPath: string): Promise<string[]>;
88
+ /**
89
+ * Return the managed cloud-file paths (relative to the project root) that
90
+ * currently exist and hold OpenSpec-generated content. Callers report this
91
+ * rather than the intended paths, so output never claims a file that a write
92
+ * skipped (user already owns it) or that reconciliation removed.
93
+ */
94
+ export declare function listManagedCloudFiles(projectPath: string): Promise<string[]>;
95
+ //# sourceMappingURL=cloud-agent.d.ts.map