@niujiajie/freespec 0.0.0-stage → 1.15.0

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 (308) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +58 -2
  3. package/bin/freespec.js +5 -0
  4. package/dist/cli/index.d.ts +25 -0
  5. package/dist/cli/index.js +359 -0
  6. package/dist/commands/shared-output.d.ts +18 -0
  7. package/dist/commands/shared-output.js +61 -0
  8. package/dist/commands/workflow/default-schema.d.ts +2 -0
  9. package/dist/commands/workflow/default-schema.js +4 -0
  10. package/dist/commands/workflow/index.d.ts +13 -0
  11. package/dist/commands/workflow/index.js +10 -0
  12. package/dist/commands/workflow/instructions.d.ts +39 -0
  13. package/dist/commands/workflow/instructions.js +565 -0
  14. package/dist/commands/workflow/new-change.d.ts +19 -0
  15. package/dist/commands/workflow/new-change.js +135 -0
  16. package/dist/commands/workflow/shared.d.ts +94 -0
  17. package/dist/commands/workflow/shared.js +169 -0
  18. package/dist/commands/workflow/status.d.ts +18 -0
  19. package/dist/commands/workflow/status.js +201 -0
  20. package/dist/core/artifact-graph/graph.d.ts +72 -0
  21. package/dist/core/artifact-graph/graph.js +165 -0
  22. package/dist/core/artifact-graph/index.d.ts +9 -0
  23. package/dist/core/artifact-graph/index.js +14 -0
  24. package/dist/core/artifact-graph/instruction-loader.d.ts +208 -0
  25. package/dist/core/artifact-graph/instruction-loader.js +268 -0
  26. package/dist/core/artifact-graph/outputs.d.ts +19 -0
  27. package/dist/core/artifact-graph/outputs.js +351 -0
  28. package/dist/core/artifact-graph/resolver.d.ts +89 -0
  29. package/dist/core/artifact-graph/resolver.js +342 -0
  30. package/dist/core/artifact-graph/schema.d.ts +27 -0
  31. package/dist/core/artifact-graph/schema.js +160 -0
  32. package/dist/core/artifact-graph/state.d.ts +12 -0
  33. package/dist/core/artifact-graph/state.js +31 -0
  34. package/dist/core/artifact-graph/types.d.ts +40 -0
  35. package/dist/core/artifact-graph/types.js +59 -0
  36. package/dist/core/available-tools.d.ts +18 -0
  37. package/dist/core/available-tools.js +49 -0
  38. package/dist/core/change-layout.d.ts +17 -0
  39. package/dist/core/change-layout.js +30 -0
  40. package/dist/core/change-metadata/index.d.ts +2 -0
  41. package/dist/core/change-metadata/index.js +2 -0
  42. package/dist/core/change-metadata/schema.d.ts +23 -0
  43. package/dist/core/change-metadata/schema.js +46 -0
  44. package/dist/core/change-status-policy.d.ts +49 -0
  45. package/dist/core/change-status-policy.js +50 -0
  46. package/dist/core/command-generation/adapters/amazon-q.d.ts +17 -0
  47. package/dist/core/command-generation/adapters/amazon-q.js +32 -0
  48. package/dist/core/command-generation/adapters/antigravity.d.ts +13 -0
  49. package/dist/core/command-generation/adapters/antigravity.js +27 -0
  50. package/dist/core/command-generation/adapters/atomcode.d.ts +24 -0
  51. package/dist/core/command-generation/adapters/atomcode.js +46 -0
  52. package/dist/core/command-generation/adapters/auggie.d.ts +13 -0
  53. package/dist/core/command-generation/adapters/auggie.js +28 -0
  54. package/dist/core/command-generation/adapters/bob.d.ts +18 -0
  55. package/dist/core/command-generation/adapters/bob.js +33 -0
  56. package/dist/core/command-generation/adapters/claude.d.ts +13 -0
  57. package/dist/core/command-generation/adapters/claude.js +32 -0
  58. package/dist/core/command-generation/adapters/cline.d.ts +14 -0
  59. package/dist/core/command-generation/adapters/cline.js +27 -0
  60. package/dist/core/command-generation/adapters/codeassistant.d.ts +15 -0
  61. package/dist/core/command-generation/adapters/codeassistant.js +29 -0
  62. package/dist/core/command-generation/adapters/codebuddy.d.ts +13 -0
  63. package/dist/core/command-generation/adapters/codebuddy.js +29 -0
  64. package/dist/core/command-generation/adapters/codestudio.d.ts +13 -0
  65. package/dist/core/command-generation/adapters/codestudio.js +27 -0
  66. package/dist/core/command-generation/adapters/command-code.d.ts +19 -0
  67. package/dist/core/command-generation/adapters/command-code.js +34 -0
  68. package/dist/core/command-generation/adapters/continue.d.ts +13 -0
  69. package/dist/core/command-generation/adapters/continue.js +33 -0
  70. package/dist/core/command-generation/adapters/costrict.d.ts +13 -0
  71. package/dist/core/command-generation/adapters/costrict.js +28 -0
  72. package/dist/core/command-generation/adapters/crush.d.ts +13 -0
  73. package/dist/core/command-generation/adapters/crush.js +30 -0
  74. package/dist/core/command-generation/adapters/cursor.d.ts +14 -0
  75. package/dist/core/command-generation/adapters/cursor.js +31 -0
  76. package/dist/core/command-generation/adapters/devin.d.ts +19 -0
  77. package/dist/core/command-generation/adapters/devin.js +36 -0
  78. package/dist/core/command-generation/adapters/easycode.d.ts +17 -0
  79. package/dist/core/command-generation/adapters/easycode.js +28 -0
  80. package/dist/core/command-generation/adapters/factory.d.ts +13 -0
  81. package/dist/core/command-generation/adapters/factory.js +28 -0
  82. package/dist/core/command-generation/adapters/gemini.d.ts +13 -0
  83. package/dist/core/command-generation/adapters/gemini.js +27 -0
  84. package/dist/core/command-generation/adapters/gigacode.d.ts +17 -0
  85. package/dist/core/command-generation/adapters/gigacode.js +31 -0
  86. package/dist/core/command-generation/adapters/github-copilot.d.ts +13 -0
  87. package/dist/core/command-generation/adapters/github-copilot.js +27 -0
  88. package/dist/core/command-generation/adapters/iflow.d.ts +13 -0
  89. package/dist/core/command-generation/adapters/iflow.js +30 -0
  90. package/dist/core/command-generation/adapters/index.d.ts +40 -0
  91. package/dist/core/command-generation/adapters/index.js +40 -0
  92. package/dist/core/command-generation/adapters/junie.d.ts +13 -0
  93. package/dist/core/command-generation/adapters/junie.js +27 -0
  94. package/dist/core/command-generation/adapters/kilocode.d.ts +14 -0
  95. package/dist/core/command-generation/adapters/kilocode.js +23 -0
  96. package/dist/core/command-generation/adapters/kiro.d.ts +13 -0
  97. package/dist/core/command-generation/adapters/kiro.js +27 -0
  98. package/dist/core/command-generation/adapters/lingma.d.ts +13 -0
  99. package/dist/core/command-generation/adapters/lingma.js +30 -0
  100. package/dist/core/command-generation/adapters/oh-my-pi.d.ts +21 -0
  101. package/dist/core/command-generation/adapters/oh-my-pi.js +42 -0
  102. package/dist/core/command-generation/adapters/opencode.d.ts +14 -0
  103. package/dist/core/command-generation/adapters/opencode.js +38 -0
  104. package/dist/core/command-generation/adapters/pi.d.ts +18 -0
  105. package/dist/core/command-generation/adapters/pi.js +39 -0
  106. package/dist/core/command-generation/adapters/qoder.d.ts +13 -0
  107. package/dist/core/command-generation/adapters/qoder.js +30 -0
  108. package/dist/core/command-generation/adapters/qwen.d.ts +17 -0
  109. package/dist/core/command-generation/adapters/qwen.js +31 -0
  110. package/dist/core/command-generation/adapters/roocode.d.ts +14 -0
  111. package/dist/core/command-generation/adapters/roocode.js +27 -0
  112. package/dist/core/command-generation/adapters/trae.d.ts +13 -0
  113. package/dist/core/command-generation/adapters/trae.js +28 -0
  114. package/dist/core/command-generation/adapters/zcode.d.ts +16 -0
  115. package/dist/core/command-generation/adapters/zcode.js +33 -0
  116. package/dist/core/command-generation/generator.d.ts +29 -0
  117. package/dist/core/command-generation/generator.js +43 -0
  118. package/dist/core/command-generation/index.d.ts +22 -0
  119. package/dist/core/command-generation/index.js +24 -0
  120. package/dist/core/command-generation/invocation.d.ts +73 -0
  121. package/dist/core/command-generation/invocation.js +77 -0
  122. package/dist/core/command-generation/registry.d.ts +36 -0
  123. package/dist/core/command-generation/registry.js +114 -0
  124. package/dist/core/command-generation/toml.d.ts +19 -0
  125. package/dist/core/command-generation/toml.js +39 -0
  126. package/dist/core/command-generation/types.d.ts +63 -0
  127. package/dist/core/command-generation/types.js +8 -0
  128. package/dist/core/command-generation/yaml.d.ts +36 -0
  129. package/dist/core/command-generation/yaml.js +48 -0
  130. package/dist/core/command-surface.d.ts +15 -0
  131. package/dist/core/command-surface.js +33 -0
  132. package/dist/core/config-prompts.d.ts +9 -0
  133. package/dist/core/config-prompts.js +56 -0
  134. package/dist/core/config-schema.d.ts +98 -0
  135. package/dist/core/config-schema.js +308 -0
  136. package/dist/core/config.d.ts +50 -0
  137. package/dist/core/config.js +122 -0
  138. package/dist/core/file-state.d.ts +36 -0
  139. package/dist/core/file-state.js +144 -0
  140. package/dist/core/file-view.d.ts +13 -0
  141. package/dist/core/file-view.js +14 -0
  142. package/dist/core/global-config.d.ts +101 -0
  143. package/dist/core/global-config.js +182 -0
  144. package/dist/core/id.d.ts +17 -0
  145. package/dist/core/id.js +30 -0
  146. package/dist/core/index.d.ts +6 -0
  147. package/dist/core/index.js +7 -0
  148. package/dist/core/init.d.ts +57 -0
  149. package/dist/core/init.js +836 -0
  150. package/dist/core/list.d.ts +11 -0
  151. package/dist/core/list.js +197 -0
  152. package/dist/core/migration.d.ts +121 -0
  153. package/dist/core/migration.js +540 -0
  154. package/dist/core/onboarding-commands.d.ts +30 -0
  155. package/dist/core/onboarding-commands.js +38 -0
  156. package/dist/core/openspec-root.d.ts +47 -0
  157. package/dist/core/openspec-root.js +196 -0
  158. package/dist/core/planning-home.d.ts +16 -0
  159. package/dist/core/planning-home.js +67 -0
  160. package/dist/core/profile-sync-drift.d.ts +31 -0
  161. package/dist/core/profile-sync-drift.js +201 -0
  162. package/dist/core/profiles.d.ts +19 -0
  163. package/dist/core/profiles.js +33 -0
  164. package/dist/core/project-config.d.ts +132 -0
  165. package/dist/core/project-config.js +519 -0
  166. package/dist/core/references.d.ts +10 -0
  167. package/dist/core/references.js +46 -0
  168. package/dist/core/root-selection.d.ts +59 -0
  169. package/dist/core/root-selection.js +132 -0
  170. package/dist/core/shared/allowed-tools.d.ts +12 -0
  171. package/dist/core/shared/allowed-tools.js +12 -0
  172. package/dist/core/shared/ide-restart.d.ts +26 -0
  173. package/dist/core/shared/ide-restart.js +42 -0
  174. package/dist/core/shared/index.d.ts +11 -0
  175. package/dist/core/shared/index.js +11 -0
  176. package/dist/core/shared/skill-content-equivalence.d.ts +7 -0
  177. package/dist/core/shared/skill-content-equivalence.js +45 -0
  178. package/dist/core/shared/skill-files.d.ts +7 -0
  179. package/dist/core/shared/skill-files.js +43 -0
  180. package/dist/core/shared/skill-generation.d.ts +49 -0
  181. package/dist/core/shared/skill-generation.js +125 -0
  182. package/dist/core/shared/skill-paths.d.ts +13 -0
  183. package/dist/core/shared/skill-paths.js +23 -0
  184. package/dist/core/shared/tool-detection.d.ts +99 -0
  185. package/dist/core/shared/tool-detection.js +318 -0
  186. package/dist/core/shared-skill-target.d.ts +51 -0
  187. package/dist/core/shared-skill-target.js +239 -0
  188. package/dist/core/store/errors.d.ts +20 -0
  189. package/dist/core/store/errors.js +22 -0
  190. package/dist/core/store/index.d.ts +2 -0
  191. package/dist/core/store/index.js +2 -0
  192. package/dist/core/styles/palette.d.ts +7 -0
  193. package/dist/core/styles/palette.js +8 -0
  194. package/dist/core/templates/optional-workflow.d.ts +69 -0
  195. package/dist/core/templates/optional-workflow.js +140 -0
  196. package/dist/core/templates/types.d.ts +19 -0
  197. package/dist/core/templates/types.js +5 -0
  198. package/dist/core/templates/workflows/personal.d.ts +22 -0
  199. package/dist/core/templates/workflows/personal.js +225 -0
  200. package/dist/core/update-plan.d.ts +127 -0
  201. package/dist/core/update-plan.js +390 -0
  202. package/dist/core/update.d.ts +154 -0
  203. package/dist/core/update.js +723 -0
  204. package/dist/core/version-check.d.ts +188 -0
  205. package/dist/core/version-check.js +906 -0
  206. package/dist/core/zod-issues.d.ts +4 -0
  207. package/dist/core/zod-issues.js +10 -0
  208. package/dist/index.d.ts +3 -0
  209. package/dist/index.js +3 -0
  210. package/dist/prompts/searchable-multi-select.d.ts +35 -0
  211. package/dist/prompts/searchable-multi-select.js +188 -0
  212. package/dist/telemetry/config.d.ts +37 -0
  213. package/dist/telemetry/config.js +148 -0
  214. package/dist/telemetry/index.d.ts +39 -0
  215. package/dist/telemetry/index.js +217 -0
  216. package/dist/telemetry/opt-out.d.ts +17 -0
  217. package/dist/telemetry/opt-out.js +27 -0
  218. package/dist/ui/ascii-patterns.d.ts +16 -0
  219. package/dist/ui/ascii-patterns.js +133 -0
  220. package/dist/ui/welcome-screen.d.ts +18 -0
  221. package/dist/ui/welcome-screen.js +199 -0
  222. package/dist/utils/change-metadata.d.ts +116 -0
  223. package/dist/utils/change-metadata.js +324 -0
  224. package/dist/utils/change-utils.d.ts +79 -0
  225. package/dist/utils/change-utils.js +121 -0
  226. package/dist/utils/ci.d.ts +12 -0
  227. package/dist/utils/ci.js +16 -0
  228. package/dist/utils/command-references.d.ts +104 -0
  229. package/dist/utils/command-references.js +190 -0
  230. package/dist/utils/date.d.ts +8 -0
  231. package/dist/utils/date.js +13 -0
  232. package/dist/utils/executable-path.d.ts +5 -0
  233. package/dist/utils/executable-path.js +44 -0
  234. package/dist/utils/file-system.d.ts +58 -0
  235. package/dist/utils/file-system.js +432 -0
  236. package/dist/utils/index.d.ts +6 -0
  237. package/dist/utils/index.js +9 -0
  238. package/dist/utils/interactive.d.ts +85 -0
  239. package/dist/utils/interactive.js +174 -0
  240. package/dist/utils/item-discovery.d.ts +15 -0
  241. package/dist/utils/item-discovery.js +33 -0
  242. package/dist/utils/line-endings.d.ts +34 -0
  243. package/dist/utils/line-endings.js +46 -0
  244. package/dist/utils/match.d.ts +3 -0
  245. package/dist/utils/match.js +22 -0
  246. package/dist/utils/nested-change.d.ts +35 -0
  247. package/dist/utils/nested-change.js +185 -0
  248. package/dist/utils/shell-detection.d.ts +20 -0
  249. package/dist/utils/shell-detection.js +94 -0
  250. package/dist/utils/task-progress.d.ts +67 -0
  251. package/dist/utils/task-progress.js +184 -0
  252. package/package.json +74 -4
  253. package/schemas//351/273/230/350/256/244/schema.yaml +68 -0
  254. package/schemas//351/273/230/350/256/244/templates//344/273/273/345/212/241/346/270/205/345/215/225.md +25 -0
  255. package/schemas//351/273/230/350/256/244/templates//346/265/213/350/257/225/347/224/250/344/276/213.md +34 -0
  256. package/schemas//351/273/230/350/256/244/templates//350/256/276/350/256/241/346/226/207/346/241/243.md +172 -0
  257. package/schemas//351/273/230/350/256/244/templates//351/234/200/346/261/202/346/226/207/346/241/243.md +19 -0
  258. package/skill-files//344/273/273/345/212/241/references//346/212/244/346/240/217.md +43 -0
  259. package/skill-files//344/273/273/345/212/241/references//347/262/222/345/272/246.md +23 -0
  260. package/skill-files//344/273/273/345/212/241/references//347/272/246/346/235/237.md +8 -0
  261. package/skill-files//344/273/273/345/212/241/scripts/check-tasks.mjs +83 -0
  262. package/skill-files//345/206/231Java/references/Java/350/247/204/350/214/203.md +25 -0
  263. package/skill-files//345/206/231Java/references//345/215/261/351/231/251/345/206/231/346/263/225.md +27 -0
  264. package/skill-files//345/206/231Java/references//345/256/214/346/210/220/345/257/271/347/205/247.md +15 -0
  265. package/skill-files//345/206/231Java/references//346/212/244/346/240/217.md +35 -0
  266. package/skill-files//345/206/231Java/references//347/272/246/346/235/237.md +8 -0
  267. package/skill-files//345/206/231Java/references//350/270/251/345/235/221.md +17 -0
  268. package/skill-files//345/256/241Java/references//346/212/244/346/240/217.md +19 -0
  269. package/skill-files//345/256/241Java/references//347/244/272/344/276/213.md +23 -0
  270. package/skill-files//345/256/241Java/references//347/272/246/346/235/237.md +7 -0
  271. package/skill-files//345/256/241Java/references//350/247/204/345/210/231.md +23 -0
  272. package/skill-files//345/256/241Java/references//351/242/206/345/237/237/346/243/200/351/241/271.md +58 -0
  273. package/skill-files//345/256/241/346/226/207/346/241/243/references//346/212/244/346/240/217.md +18 -0
  274. package/skill-files//345/256/241/346/226/207/346/241/243/references//347/272/246/346/235/237.md +8 -0
  275. package/skill-files//345/256/241/346/226/207/346/241/243/references//347/273/264/345/272/246.md +17 -0
  276. package/skill-files//345/256/241/346/226/207/346/241/243/references//350/270/251/345/235/221.md +11 -0
  277. package/skill-files//346/226/260/345/273/272/references//344/272/244/346/216/245.md +11 -0
  278. package/skill-files//346/226/260/345/273/272/references//346/212/244/346/240/217.md +14 -0
  279. package/skill-files//346/226/260/345/273/272/references//347/272/246/346/235/237.md +7 -0
  280. package/skill-files//346/267/261/346/200/235/config/prompts.yaml +114 -0
  281. package/skill-files//346/267/261/346/200/235/references//344/270/211/346/226/271/346/240/270/345/257/271.md +72 -0
  282. package/skill-files//346/267/261/346/200/235/references//344/276/213/345/255/220.md +39 -0
  283. package/skill-files//346/267/261/346/200/235/references//346/200/216/344/271/210/346/203/263.md +61 -0
  284. package/skill-files//346/267/261/346/200/235/references//346/212/244/346/240/217.md +26 -0
  285. package/skill-files//346/267/261/346/200/235/references//347/202/271/351/200/211/346/217/220/351/227/256.md +66 -0
  286. package/skill-files//346/267/261/346/200/235/references//347/231/273/350/256/260.md +45 -0
  287. package/skill-files//346/267/261/346/200/235/references//347/272/246/346/235/237.md +9 -0
  288. package/skill-files//347/224/250/344/276/213/references//346/200/216/344/271/210/345/206/231.md +13 -0
  289. package/skill-files//347/224/250/344/276/213/references//346/212/244/346/240/217.md +42 -0
  290. package/skill-files//347/224/250/344/276/213/references//347/272/246/346/235/237.md +5 -0
  291. package/skill-files//347/224/250/344/276/213/scripts/check-cases.mjs +70 -0
  292. package/skill-files//350/256/276/350/256/241/references//345/207/206/345/244/207.md +25 -0
  293. package/skill-files//350/256/276/350/256/241/references//346/212/244/346/240/217.md +134 -0
  294. package/skill-files//350/256/276/350/256/241/references//346/226/207/351/243/216.md +17 -0
  295. package/skill-files//350/256/276/350/256/241/references//347/225/214/351/235/242.md +18 -0
  296. package/skill-files//350/256/276/350/256/241/references//347/261/273/345/236/213.md +19 -0
  297. package/skill-files//350/256/276/350/256/241/references//347/272/246/346/235/237.md +25 -0
  298. package/skill-files//350/256/276/350/256/241/scripts/_smoke.mjs +72 -0
  299. package/skill-files//350/256/276/350/256/241/scripts/check-design.mjs +331 -0
  300. package/skill-files//351/234/200/346/261/202/references//346/212/244/346/240/217.md +26 -0
  301. package/skill-files//351/234/200/346/261/202/references//346/226/207/351/243/216.md +23 -0
  302. package/skill-files//351/234/200/346/261/202/references//346/267/261/346/200/235/346/221/204/345/205/245.md +21 -0
  303. package/skill-files//351/234/200/346/261/202/references//347/272/246/346/235/237.md +8 -0
  304. package/skill-files//351/234/200/346/261/202/references//351/234/200/346/261/202/345/276/205/345/256/232.md +13 -0
  305. package/skill-files//351/234/200/346/261/202/scripts/check-requirements.mjs +60 -0
  306. package/skill-files//351/252/214/346/224/266/references//346/212/244/346/240/217.md +27 -0
  307. package/skill-files//351/252/214/346/224/266/references//346/240/270/345/257/271.md +17 -0
  308. package/skill-files//351/252/214/346/224/266/references//347/272/246/346/235/237.md +7 -0
@@ -0,0 +1,4 @@
1
+ import type { z } from 'zod';
2
+ /** One rendering for zod issues across every state/config parser. */
3
+ export declare function formatZodIssues(error: z.ZodError, fallbackLocation?: string): string;
4
+ //# sourceMappingURL=zod-issues.d.ts.map
@@ -0,0 +1,10 @@
1
+ /** One rendering for zod issues across every state/config parser. */
2
+ export function formatZodIssues(error, fallbackLocation = 'root') {
3
+ return error.issues
4
+ .map((issue) => {
5
+ const location = issue.path.length > 0 ? issue.path.join('.') : fallbackLocation;
6
+ return `${location}: ${issue.message}`;
7
+ })
8
+ .join('; ');
9
+ }
10
+ //# sourceMappingURL=zod-issues.js.map
@@ -0,0 +1,3 @@
1
+ export * from './cli/index.js';
2
+ export * from './core/index.js';
3
+ //# sourceMappingURL=index.d.ts.map
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ export * from './cli/index.js';
2
+ export * from './core/index.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,35 @@
1
+ interface Choice {
2
+ name: string;
3
+ value: string;
4
+ /**
5
+ * Extra terms the search box matches, for choices users look for by a word
6
+ * the name does not spell (see #653). Never rendered.
7
+ */
8
+ searchAliases?: string[];
9
+ description?: string;
10
+ configured?: boolean;
11
+ detected?: boolean;
12
+ configuredLabel?: string;
13
+ preSelected?: boolean;
14
+ }
15
+ interface Config {
16
+ message: string;
17
+ choices: Choice[];
18
+ pageSize?: number;
19
+ validate?: (selected: string[]) => boolean | string;
20
+ /** Shown when a search matches nothing, so the list is not a dead end. */
21
+ emptyHint?: string;
22
+ }
23
+ /**
24
+ * A searchable multi-select prompt with visible search box,
25
+ * selected items display, and intuitive keyboard navigation.
26
+ *
27
+ * - Type to filter choices
28
+ * - ↑↓ to navigate
29
+ * - Space to toggle highlighted item selection
30
+ * - Backspace to remove last selected item (or delete search char)
31
+ * - Enter to confirm selections
32
+ */
33
+ export declare function searchableMultiSelect(config: Config): Promise<string[]>;
34
+ export default searchableMultiSelect;
35
+ //# sourceMappingURL=searchable-multi-select.d.ts.map
@@ -0,0 +1,188 @@
1
+ import chalk from 'chalk';
2
+ /**
3
+ * True when every character is printable, so the text can go in the search box.
4
+ * `\u007f` is DEL, which sorts above the printable range.
5
+ */
6
+ function isPrintable(text) {
7
+ return text.length > 0 && [...text].every((char) => char >= ' ' && char !== '\u007f');
8
+ }
9
+ /**
10
+ * Create the searchable multi-select prompt.
11
+ * Uses dynamic import to prevent pre-commit hook hangs (see #367).
12
+ */
13
+ async function createSearchableMultiSelect() {
14
+ const { createPrompt, useState, useKeypress, useMemo, usePrefix, isEnterKey, isBackspaceKey, isUpKey, isDownKey, } = await import('@inquirer/core');
15
+ return createPrompt((config, done) => {
16
+ const { message, choices, pageSize = 15, validate, emptyHint } = config;
17
+ const [searchText, setSearchText] = useState('');
18
+ const [selectedValues, setSelectedValues] = useState(() => choices.filter(c => c.preSelected).map(c => c.value));
19
+ const [cursor, setCursor] = useState(0);
20
+ const [status, setStatus] = useState('idle');
21
+ const [error, setError] = useState(null);
22
+ const prefix = usePrefix({ status });
23
+ // Filter choices by search
24
+ const filteredChoices = useMemo(() => {
25
+ if (!searchText.trim())
26
+ return choices;
27
+ const term = searchText.trim().toLowerCase();
28
+ return choices.filter((c) => c.name.toLowerCase().includes(term) ||
29
+ c.value.toLowerCase().includes(term) ||
30
+ (c.searchAliases ?? []).some((alias) => alias.toLowerCase().includes(term)));
31
+ }, [searchText, choices]);
32
+ const selectedSet = useMemo(() => new Set(selectedValues), [selectedValues]);
33
+ const choiceMap = useMemo(() => new Map(choices.map((c) => [c.value, c])), [choices]);
34
+ useKeypress((key) => {
35
+ if (status === 'done')
36
+ return;
37
+ // Enter to confirm/submit
38
+ if (isEnterKey(key)) {
39
+ if (validate) {
40
+ const result = validate(selectedValues);
41
+ if (result !== true) {
42
+ setError(typeof result === 'string' ? result : 'Invalid');
43
+ return;
44
+ }
45
+ }
46
+ setStatus('done');
47
+ done(selectedValues);
48
+ return;
49
+ }
50
+ // Space to toggle selection
51
+ if (key.name === 'space') {
52
+ const choice = filteredChoices[cursor];
53
+ if (choice) {
54
+ if (selectedSet.has(choice.value)) {
55
+ setSelectedValues(selectedValues.filter(v => v !== choice.value));
56
+ }
57
+ else {
58
+ setSelectedValues([...selectedValues, choice.value]);
59
+ }
60
+ }
61
+ return;
62
+ }
63
+ // Backspace to remove or delete search char
64
+ if (isBackspaceKey(key)) {
65
+ if (searchText === '' && selectedValues.length > 0) {
66
+ setSelectedValues(selectedValues.slice(0, -1));
67
+ }
68
+ else {
69
+ setSearchText(searchText.slice(0, -1));
70
+ setCursor(0);
71
+ }
72
+ return;
73
+ }
74
+ // Navigation
75
+ if (isUpKey(key)) {
76
+ setCursor(Math.max(0, cursor - 1));
77
+ return;
78
+ }
79
+ if (isDownKey(key)) {
80
+ setCursor(Math.min(filteredChoices.length - 1, cursor + 1));
81
+ return;
82
+ }
83
+ // Character input - handle printable characters.
84
+ // readline reports punctuation (`.`, `-`, `/`) only in `sequence`, leaving
85
+ // `name` undefined, so keying off `name` alone silently dropped every
86
+ // non-alphanumeric character the user typed.
87
+ // `@inquirer/core` types only `name` and `ctrl`; readline emits more.
88
+ const event = key;
89
+ if (event.ctrl || event.meta)
90
+ return;
91
+ // Requiring every character to be printable drops escape sequences
92
+ // (arrows, function keys), tab, escape and delete. readline splits a
93
+ // paste into one key per character, so a pasted space still toggles.
94
+ const typed = typeof event.sequence === 'string' && isPrintable(event.sequence)
95
+ ? event.sequence
96
+ : // Only the sequence may be multi-character: readline `name`s such as
97
+ // 'tab' and 'escape' are printable strings but not typed input.
98
+ typeof event.name === 'string' &&
99
+ event.name.length === 1 &&
100
+ isPrintable(event.name)
101
+ ? event.name
102
+ : undefined;
103
+ if (typed) {
104
+ setSearchText(searchText + typed);
105
+ setCursor(0);
106
+ }
107
+ });
108
+ // Render done state
109
+ if (status === 'done') {
110
+ const names = selectedValues
111
+ .map((v) => choiceMap.get(v)?.name ?? v)
112
+ .join(', ');
113
+ return `${prefix} ${chalk.bold(message)} ${chalk.cyan(names || '(none)')}`;
114
+ }
115
+ // Render active state
116
+ const lines = [];
117
+ lines.push(`${prefix} ${chalk.bold(message)}`);
118
+ // Selected chips
119
+ const chips = selectedValues.length > 0
120
+ ? selectedValues
121
+ .map((v) => chalk.bgCyan.black(` ${choiceMap.get(v)?.name} `))
122
+ .join(' ')
123
+ : chalk.dim('(none selected)');
124
+ lines.push(` Selected: ${chips}`);
125
+ // Search box
126
+ lines.push(` Search: ${chalk.yellow('[')}${searchText || chalk.dim('type to filter')}${chalk.yellow(']')}`);
127
+ // Instructions
128
+ lines.push(` ${chalk.cyan('↑↓')} navigate • ${chalk.cyan('Space')} toggle • ${chalk.cyan('Backspace')} remove • ${chalk.cyan('Enter')} confirm`);
129
+ // List
130
+ if (filteredChoices.length === 0) {
131
+ lines.push(chalk.yellow(' No matches'));
132
+ if (emptyHint)
133
+ lines.push(chalk.dim(` ${emptyHint}`));
134
+ }
135
+ else {
136
+ // Calculate pagination
137
+ const startIndex = Math.max(0, Math.min(cursor - Math.floor(pageSize / 2), filteredChoices.length - pageSize));
138
+ const endIndex = Math.min(startIndex + pageSize, filteredChoices.length);
139
+ const visibleChoices = filteredChoices.slice(startIndex, endIndex);
140
+ for (let i = 0; i < visibleChoices.length; i++) {
141
+ const item = visibleChoices[i];
142
+ const actualIndex = startIndex + i;
143
+ const isActive = actualIndex === cursor;
144
+ const selected = selectedSet.has(item.value);
145
+ const icon = selected ? chalk.green('[x]') : chalk.dim('[ ]');
146
+ const arrow = isActive ? chalk.cyan('›') : ' ';
147
+ const name = isActive ? chalk.cyan(item.name) : item.name;
148
+ const isRefresh = selected && item.configured;
149
+ const statusLabel = !selected
150
+ ? item.configured
151
+ ? ' (configured)'
152
+ : item.detected
153
+ ? ' (detected)'
154
+ : ''
155
+ : '';
156
+ const suffix = selected
157
+ ? chalk.dim(isRefresh ? ' (refresh)' : ' (selected)')
158
+ : chalk.dim(statusLabel);
159
+ lines.push(` ${arrow} ${icon} ${name}${suffix}`);
160
+ }
161
+ // Show pagination indicator if needed
162
+ if (filteredChoices.length > pageSize) {
163
+ const currentPage = Math.floor(cursor / pageSize) + 1;
164
+ const totalPages = Math.ceil(filteredChoices.length / pageSize);
165
+ lines.push(chalk.dim(` (${currentPage}/${totalPages})`));
166
+ }
167
+ }
168
+ if (error)
169
+ lines.push(chalk.red(` ${error}`));
170
+ return lines.join('\n');
171
+ });
172
+ }
173
+ /**
174
+ * A searchable multi-select prompt with visible search box,
175
+ * selected items display, and intuitive keyboard navigation.
176
+ *
177
+ * - Type to filter choices
178
+ * - ↑↓ to navigate
179
+ * - Space to toggle highlighted item selection
180
+ * - Backspace to remove last selected item (or delete search char)
181
+ * - Enter to confirm selections
182
+ */
183
+ export async function searchableMultiSelect(config) {
184
+ const prompt = await createSearchableMultiSelect();
185
+ return prompt(config);
186
+ }
187
+ export default searchableMultiSelect;
188
+ //# sourceMappingURL=searchable-multi-select.js.map
@@ -0,0 +1,37 @@
1
+ import { type TelemetryConfig } from '../core/global-config.js';
2
+ export declare const CONFIG_DIR_NAME = "freespec";
3
+ export declare const CONFIG_FILE_NAME = "config.json";
4
+ /** Re-export shared telemetry section type (single source of truth in global-config). */
5
+ export type { TelemetryConfig };
6
+ export interface GlobalConfig {
7
+ telemetry?: TelemetryConfig;
8
+ [key: string]: unknown;
9
+ }
10
+ /**
11
+ * Get the path to the global config file.
12
+ * Follows XDG Base Directory Specification and platform conventions.
13
+ *
14
+ * - All platforms: $XDG_CONFIG_HOME/freespec/ if XDG_CONFIG_HOME is set
15
+ * - Unix/macOS fallback: ~/.config/freespec/
16
+ * - Windows fallback: %APPDATA%/freespec/
17
+ */
18
+ export declare function getConfigPath(): string;
19
+ /**
20
+ * Read the global config file.
21
+ * Returns an empty object if the file doesn't exist.
22
+ */
23
+ export declare function readConfig(): Promise<GlobalConfig>;
24
+ /**
25
+ * Write to the global config file.
26
+ * Preserves existing fields and merges in new values.
27
+ */
28
+ export declare function writeConfig(updates: Partial<GlobalConfig>): Promise<void>;
29
+ /**
30
+ * Get the telemetry config section.
31
+ */
32
+ export declare function getTelemetryConfig(): Promise<TelemetryConfig>;
33
+ /**
34
+ * Update the telemetry config section.
35
+ */
36
+ export declare function updateTelemetryConfig(updates: Partial<TelemetryConfig>): Promise<void>;
37
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1,148 @@
1
+ /**
2
+ * Global configuration for telemetry state.
3
+ * Stores anonymous ID and notice-seen flag in the platform-appropriate config directory.
4
+ */
5
+ import { promises as fs } from 'fs';
6
+ import path from 'path';
7
+ import os from 'os';
8
+ import { GLOBAL_CONFIG_DIR_NAME, GLOBAL_CONFIG_FILE_NAME, getGlobalConfigDir, isConfigRootObject, unreadableGlobalConfigMessage, } from '../core/global-config.js';
9
+ // Constants
10
+ export const CONFIG_DIR_NAME = GLOBAL_CONFIG_DIR_NAME;
11
+ export const CONFIG_FILE_NAME = GLOBAL_CONFIG_FILE_NAME;
12
+ function getConfigDir() {
13
+ return getGlobalConfigDir();
14
+ }
15
+ function getLegacyConfigPath() {
16
+ return path.join(os.homedir(), '.config', CONFIG_DIR_NAME, CONFIG_FILE_NAME);
17
+ }
18
+ async function readConfigFile(configPath) {
19
+ try {
20
+ const content = await fs.readFile(configPath, 'utf-8');
21
+ const parsed = JSON.parse(content);
22
+ // Valid JSON that is not an object carries no settings to merge into, and
23
+ // spreading it would replace the file (a string even spreads to numeric
24
+ // character keys). Same predicate the rest of the CLI refuses to save over.
25
+ if (!isConfigRootObject(parsed)) {
26
+ return { status: 'invalid', config: {} };
27
+ }
28
+ return { status: 'ok', config: parsed };
29
+ }
30
+ catch (error) {
31
+ if (error.code === 'ENOENT') {
32
+ return { status: 'missing' };
33
+ }
34
+ // If parse fails or another read error occurs, ignore the file.
35
+ return { status: 'invalid', config: {} };
36
+ }
37
+ }
38
+ async function writeConfigFile(configPath, config) {
39
+ await fs.mkdir(path.dirname(configPath), { recursive: true });
40
+ await fs.writeFile(configPath, JSON.stringify(config, null, 2) + '\n');
41
+ }
42
+ function hasMissingTelemetryFields(config) {
43
+ const telemetry = config.telemetry;
44
+ return (!telemetry ||
45
+ telemetry.anonymousId === undefined ||
46
+ telemetry.noticeSeen === undefined);
47
+ }
48
+ function mergeLegacyTelemetry(config, legacyConfig) {
49
+ const legacyTelemetry = legacyConfig.telemetry;
50
+ if (!legacyTelemetry) {
51
+ return undefined;
52
+ }
53
+ const currentTelemetry = config.telemetry ?? {};
54
+ const shouldMigrate = (currentTelemetry.anonymousId === undefined && legacyTelemetry.anonymousId !== undefined) ||
55
+ (currentTelemetry.noticeSeen === undefined && legacyTelemetry.noticeSeen !== undefined);
56
+ if (!shouldMigrate) {
57
+ return undefined;
58
+ }
59
+ return {
60
+ ...config,
61
+ telemetry: {
62
+ ...legacyTelemetry,
63
+ ...currentTelemetry,
64
+ },
65
+ };
66
+ }
67
+ async function migrateLegacyTelemetryConfig(configPath, config, persist) {
68
+ const legacyConfigPath = getLegacyConfigPath();
69
+ if (path.resolve(configPath) === path.resolve(legacyConfigPath) || !hasMissingTelemetryFields(config)) {
70
+ return config;
71
+ }
72
+ const legacyRead = await readConfigFile(legacyConfigPath);
73
+ if (legacyRead.status !== 'ok') {
74
+ return config;
75
+ }
76
+ const migrated = mergeLegacyTelemetry(config, legacyRead.config);
77
+ if (!migrated) {
78
+ return config;
79
+ }
80
+ if (persist) {
81
+ try {
82
+ await writeConfigFile(configPath, migrated);
83
+ }
84
+ catch {
85
+ // Preserve telemetry for this run even if the one-time migration cannot be persisted.
86
+ }
87
+ }
88
+ return migrated;
89
+ }
90
+ /**
91
+ * Get the path to the global config file.
92
+ * Follows XDG Base Directory Specification and platform conventions.
93
+ *
94
+ * - All platforms: $XDG_CONFIG_HOME/freespec/ if XDG_CONFIG_HOME is set
95
+ * - Unix/macOS fallback: ~/.config/freespec/
96
+ * - Windows fallback: %APPDATA%/freespec/
97
+ */
98
+ export function getConfigPath() {
99
+ const configDir = getConfigDir();
100
+ return path.join(configDir, CONFIG_FILE_NAME);
101
+ }
102
+ /**
103
+ * Read the global config file.
104
+ * Returns an empty object if the file doesn't exist.
105
+ */
106
+ export async function readConfig() {
107
+ const configPath = getConfigPath();
108
+ const read = await readConfigFile(configPath);
109
+ const config = read.status === 'ok' ? read.config : {};
110
+ return migrateLegacyTelemetryConfig(configPath, config, read.status !== 'invalid');
111
+ }
112
+ /**
113
+ * Write to the global config file.
114
+ * Preserves existing fields and merges in new values.
115
+ */
116
+ export async function writeConfig(updates) {
117
+ const configPath = getConfigPath();
118
+ // Never write over a file that did not parse: the merge below would start
119
+ // from an empty object and replace every setting in it with these updates.
120
+ if ((await readConfigFile(configPath)).status === 'invalid') {
121
+ throw new Error(unreadableGlobalConfigMessage(configPath));
122
+ }
123
+ // Read existing config and merge
124
+ const existing = await readConfig();
125
+ const merged = { ...existing, ...updates };
126
+ // Deep merge for telemetry object
127
+ if (updates.telemetry && existing.telemetry) {
128
+ merged.telemetry = { ...existing.telemetry, ...updates.telemetry };
129
+ }
130
+ await writeConfigFile(configPath, merged);
131
+ }
132
+ /**
133
+ * Get the telemetry config section.
134
+ */
135
+ export async function getTelemetryConfig() {
136
+ const config = await readConfig();
137
+ return config.telemetry ?? {};
138
+ }
139
+ /**
140
+ * Update the telemetry config section.
141
+ */
142
+ export async function updateTelemetryConfig(updates) {
143
+ const existing = await getTelemetryConfig();
144
+ await writeConfig({
145
+ telemetry: { ...existing, ...updates },
146
+ });
147
+ }
148
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Check if telemetry is enabled.
3
+ *
4
+ * Precedence (first match wins):
5
+ * 1. OPENSPEC_TELEMETRY set to anything but an on-value (1/true/yes/on) → disabled
6
+ * 2. DO_NOT_TRACK set to anything but an off-value (0/false/no/off) → disabled
7
+ * 3. CI set to a truthy/on value → disabled (same rule as version-check)
8
+ * 4. global config telemetry.enabled === false → disabled
9
+ * 5. global config file exists but cannot be parsed → disabled
10
+ * 6. otherwise enabled (unset config means on; opt-out model)
11
+ *
12
+ * Kept synchronous so call sites need not become async. Reads config via
13
+ * sync getGlobalConfig() rather than async getTelemetryConfig().
14
+ */
15
+ export declare function isTelemetryEnabled(): boolean;
16
+ /**
17
+ * Get or create the anonymous user ID.
18
+ * Lazily generates a UUID on first call and persists it.
19
+ */
20
+ export declare function getOrCreateAnonymousId(): Promise<string>;
21
+ /**
22
+ * Track a command execution.
23
+ *
24
+ * @param commandName - The command name (e.g., 'init', 'change:apply')
25
+ * @param version - The FreeSpec version
26
+ */
27
+ export declare function trackCommand(commandName: string, version: string): Promise<void>;
28
+ /**
29
+ * Show first-run telemetry notice if not already seen.
30
+ */
31
+ export declare function maybeShowTelemetryNotice(options?: {
32
+ silent?: boolean;
33
+ }): Promise<void>;
34
+ /**
35
+ * Flush pending telemetry events.
36
+ * Call this before CLI exit.
37
+ */
38
+ export declare function shutdown(): Promise<void>;
39
+ //# sourceMappingURL=index.d.ts.map