@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,11 @@
1
+ import type { RootOutput } from './root-selection.js';
2
+ interface ListOptions {
3
+ sort?: 'recent' | 'name';
4
+ json?: boolean;
5
+ root?: RootOutput;
6
+ }
7
+ export declare class ListCommand {
8
+ execute(targetPath?: string, options?: ListOptions): Promise<void>;
9
+ }
10
+ export {};
11
+ //# sourceMappingURL=list.d.ts.map
@@ -0,0 +1,197 @@
1
+ import { promises as fs } from 'fs';
2
+ import path from 'path';
3
+ import { getTaskProgressForChange, formatTaskStatus } from '../utils/task-progress.js';
4
+ import { describeNestedChange, findNestedChanges, } from '../utils/nested-change.js';
5
+ import { changeParentDir, isChangeDirectoryName } from './change-layout.js';
6
+ function isMissingPathError(error) {
7
+ return (typeof error === 'object' &&
8
+ error !== null &&
9
+ 'code' in error &&
10
+ error.code === 'ENOENT');
11
+ }
12
+ /**
13
+ * An entry that cannot be dated because it no longer resolves: it was removed
14
+ * after `readdir` listed it, or it is a symlink whose target is missing (an
15
+ * Emacs `.#file` lock) or that loops back on itself.
16
+ */
17
+ function isUnresolvableEntryError(error) {
18
+ if (typeof error !== 'object' || error === null || !('code' in error))
19
+ return false;
20
+ const code = error.code;
21
+ return code === 'ENOENT' || code === 'ELOOP';
22
+ }
23
+ async function readChangeDirectoryEntries(changesDir) {
24
+ try {
25
+ return await fs.readdir(changesDir, { withFileTypes: true });
26
+ }
27
+ catch (error) {
28
+ if (isMissingPathError(error))
29
+ return [];
30
+ throw error;
31
+ }
32
+ }
33
+ /**
34
+ * Get the most recent modification time of any file in a directory (recursive).
35
+ * Falls back to the directory's own mtime if no files are found.
36
+ * Archived links use their own mtime: moving a change can break relative targets.
37
+ */
38
+ async function getLastModified(dirPath, archived = false) {
39
+ let latest = null;
40
+ async function walk(dir) {
41
+ const entries = await fs.readdir(dir, { withFileTypes: true });
42
+ for (const entry of entries) {
43
+ const fullPath = path.join(dir, entry.name);
44
+ try {
45
+ if (entry.isDirectory()) {
46
+ await walk(fullPath);
47
+ }
48
+ else {
49
+ const stat = archived && entry.isSymbolicLink()
50
+ ? await fs.lstat(fullPath)
51
+ : await fs.stat(fullPath);
52
+ if (latest === null || stat.mtime > latest) {
53
+ latest = stat.mtime;
54
+ }
55
+ }
56
+ }
57
+ catch (error) {
58
+ // Skip the one entry rather than fail the listing of every change.
59
+ if (!isUnresolvableEntryError(error))
60
+ throw error;
61
+ }
62
+ }
63
+ }
64
+ await walk(dirPath);
65
+ // If no files found, use the directory's own modification time
66
+ if (latest === null) {
67
+ const dirStat = await fs.stat(dirPath);
68
+ return dirStat.mtime;
69
+ }
70
+ return latest;
71
+ }
72
+ /**
73
+ * Format a date as relative time (e.g., "2 hours ago", "3 days ago")
74
+ */
75
+ function formatRelativeTime(date) {
76
+ const now = new Date();
77
+ const diffMs = now.getTime() - date.getTime();
78
+ const diffSecs = Math.floor(diffMs / 1000);
79
+ const diffMins = Math.floor(diffSecs / 60);
80
+ const diffHours = Math.floor(diffMins / 60);
81
+ const diffDays = Math.floor(diffHours / 24);
82
+ if (diffDays > 30) {
83
+ return date.toLocaleDateString();
84
+ }
85
+ else if (diffDays > 0) {
86
+ return `${diffDays}d ago`;
87
+ }
88
+ else if (diffHours > 0) {
89
+ return `${diffHours}h ago`;
90
+ }
91
+ else if (diffMins > 0) {
92
+ return `${diffMins}m ago`;
93
+ }
94
+ else {
95
+ return 'just now';
96
+ }
97
+ }
98
+ export class ListCommand {
99
+ async execute(targetPath = '.', options = {}) {
100
+ const { sort = 'recent', json = false, root } = options;
101
+ {
102
+ const changesDir = changeParentDir(targetPath);
103
+ const entries = await readChangeDirectoryEntries(changesDir);
104
+ const changeDirs = entries
105
+ .filter(entry => entry.isDirectory() && isChangeDirectoryName(entry.name))
106
+ .map(entry => ({ name: entry.name, parent: changesDir, archived: false }));
107
+ if (changeDirs.length === 0) {
108
+ if (json) {
109
+ console.log(JSON.stringify({ changes: [], ...(root ? { root } : {}) }, null, 2));
110
+ }
111
+ else {
112
+ console.log('No active changes found.');
113
+ }
114
+ return;
115
+ }
116
+ // Collect information about each change
117
+ const changes = [];
118
+ // A directory that only wraps nested change directories is still listed -
119
+ // hiding it would hide a real change whenever the probe is wrong - but it
120
+ // is listed as what it is, so the nesting stops failing silently (#1846).
121
+ const nestedFindings = await findNestedChanges(changesDir, changeDirs.map((changeDir) => changeDir.name));
122
+ const nestedByName = new Map(nestedFindings.map((finding) => [finding.name, finding]));
123
+ for (const changeDir of changeDirs) {
124
+ const progress = await getTaskProgressForChange(changeDir.parent, changeDir.name, targetPath);
125
+ const changePath = path.join(changeDir.parent, changeDir.name);
126
+ const lastModified = await getLastModified(changePath, changeDir.archived);
127
+ changes.push({
128
+ name: changeDir.name,
129
+ completedTasks: progress.completed,
130
+ totalTasks: progress.total,
131
+ lastModified,
132
+ archived: changeDir.archived,
133
+ ...(!changeDir.archived && nestedByName.has(changeDir.name)
134
+ ? { nested: nestedByName.get(changeDir.name).nested }
135
+ : {})
136
+ });
137
+ }
138
+ // Sort by preference (default: recent first)
139
+ if (sort === 'recent') {
140
+ changes.sort((a, b) => b.lastModified.getTime() - a.lastModified.getTime());
141
+ }
142
+ else {
143
+ changes.sort((a, b) => a.name.localeCompare(b.name));
144
+ }
145
+ // JSON output for programmatic use
146
+ if (json) {
147
+ const jsonOutput = changes.map(c => ({
148
+ name: c.name,
149
+ completedTasks: c.completedTasks,
150
+ totalTasks: c.totalTasks,
151
+ lastModified: c.lastModified.toISOString(),
152
+ status: c.totalTasks === 0 ? 'no-tasks' : c.completedTasks === c.totalTasks ? 'complete' : 'in-progress',
153
+ ...(c.nested ? { nested: c.nested } : {})
154
+ }));
155
+ // Additive: the entries keep their shape so existing consumers are
156
+ // unaffected, and the nesting is reported alongside them.
157
+ const warnings = nestedFindings.map((finding) => ({
158
+ code: 'nested_change_directory',
159
+ name: finding.name,
160
+ nested: finding.nested,
161
+ message: describeNestedChange(finding)
162
+ }));
163
+ console.log(JSON.stringify({
164
+ changes: jsonOutput,
165
+ ...(warnings.length > 0 ? { warnings } : {}),
166
+ ...(root ? { root } : {})
167
+ }, null, 2));
168
+ return;
169
+ }
170
+ // Display results
171
+ const groups = [
172
+ { heading: 'Changes:', changes: changes.filter(change => !change.archived) },
173
+ { heading: 'Archived Changes:', changes: changes.filter(change => change.archived) }
174
+ ].filter(group => group.changes.length > 0);
175
+ for (const [index, group] of groups.entries()) {
176
+ if (index > 0)
177
+ console.log('');
178
+ console.log(group.heading);
179
+ const padding = ' ';
180
+ const nameWidth = Math.max(...group.changes.map(c => c.name.length));
181
+ for (const change of group.changes) {
182
+ const paddedName = change.name.padEnd(nameWidth);
183
+ const status = change.nested
184
+ ? 'not a change'
185
+ : formatTaskStatus({ total: change.totalTasks, completed: change.completedTasks });
186
+ const timeAgo = formatRelativeTime(change.lastModified);
187
+ console.log(`${padding}${paddedName} ${status.padEnd(12)} ${timeAgo}`);
188
+ }
189
+ }
190
+ for (const finding of nestedFindings) {
191
+ console.log('');
192
+ console.log(`Warning: ${describeNestedChange(finding)}`);
193
+ }
194
+ }
195
+ }
196
+ }
197
+ //# sourceMappingURL=list.js.map
@@ -0,0 +1,121 @@
1
+ /**
2
+ * Migration Utilities
3
+ *
4
+ * One-time migration logic for existing projects when profile system is introduced.
5
+ * Called by both init and update commands before profile resolution.
6
+ */
7
+ import { type AIToolOption } from './config.js';
8
+ import { type Delivery, type GlobalConfig, type Profile } from './global-config.js';
9
+ import { type FileView } from './file-view.js';
10
+ export interface LegacyToolRoot {
11
+ /** Former tool root, e.g. '.kimi' */
12
+ root: string;
13
+ /**
14
+ * Whether leaving this root requires the user's say-so. False when the old
15
+ * product is gone and its directory is certainly dead. True when the old
16
+ * location may still be the live one for somebody.
17
+ */
18
+ needsConsent: boolean;
19
+ /** Migrations that need a freshly generated destination run afterward. */
20
+ timing?: 'before-generation' | 'after-generation';
21
+ }
22
+ /**
23
+ * Former tool roots whose FreeSpec-managed content belongs under the tool's
24
+ * current skillsDir. User files are never touched.
25
+ */
26
+ export declare const LEGACY_TOOL_ROOTS: Record<string, LegacyToolRoot[]>;
27
+ export interface LegacyToolMigration {
28
+ toolId: string;
29
+ /** Legacy tool root, e.g. '.windsurf' */
30
+ from: string;
31
+ /** Current tool root, e.g. '.devin' */
32
+ to: string;
33
+ /** Skill directories that moved, or would move */
34
+ skillDirs: number;
35
+ /** Command files that moved, or would move */
36
+ commandFiles: number;
37
+ /**
38
+ * FreeSpec-managed files left under the legacy root because the copy there
39
+ * differs materially from the one that survives, so it is reported rather
40
+ * than dropped.
41
+ */
42
+ keptInPlace: number;
43
+ /** Whether this move needs the user's consent first */
44
+ needsConsent: boolean;
45
+ }
46
+ /** One file a legacy-root migration would move or drop. */
47
+ export interface LegacyMigrationFileOp {
48
+ toolId: string;
49
+ source: string;
50
+ destination: string;
51
+ disposition: 'move' | 'drop';
52
+ /** Whether an interactive run asks before this move */
53
+ needsConsent: boolean;
54
+ }
55
+ /**
56
+ * Reports the FreeSpec content sitting under each tool's legacy root, without
57
+ * moving anything. Callers use this to ask before a move that needs consent.
58
+ */
59
+ export declare function findLegacyToolMigrations(projectPath: string, timing?: 'before-generation' | 'after-generation'): LegacyToolMigration[];
60
+ /**
61
+ * Lists, file by file, what `migrateLegacyToolDirs` would move or drop, without
62
+ * touching anything. Consent-gated roots are included: a non-interactive run
63
+ * moves them without asking. `view` decides what already sits at each
64
+ * destination, so a dry run can plan against files it has not written.
65
+ */
66
+ export declare function planLegacyToolMigrations(projectPath: string, timing: 'before-generation' | 'after-generation', toolIds: string[] | undefined, view: FileView): LegacyMigrationFileOp[];
67
+ /**
68
+ * Moves FreeSpec-managed skill directories (freespec-*) and command files
69
+ * (freespec-*) from a tool's legacy root to its current one. When the destination
70
+ * already exists the legacy copy is removed instead. Legacy directories are
71
+ * deleted only when left empty, so user files under the old location — a
72
+ * hand-written Cascade workflow next to the generated ones — are preserved.
73
+ *
74
+ * @param projectPath - Project root
75
+ * @param toolIds - Restrict the move to these tools; omit to move every tool
76
+ * whose legacy root needs no consent
77
+ */
78
+ export declare function migrateLegacyToolDirs(projectPath: string, toolIds?: string[], timing?: 'before-generation' | 'after-generation'): LegacyToolMigration[];
79
+ /**
80
+ * Summarizes what a migration moved, e.g. "6 skills and 6 commands".
81
+ */
82
+ export declare function describeLegacyMigration(migration: LegacyToolMigration): string;
83
+ /**
84
+ * Names FreeSpec-managed files the move deliberately left behind, so a user
85
+ * who customized one knows there are now two copies to reconcile.
86
+ */
87
+ export declare function keptInPlaceNotice(migration: LegacyToolMigration): string | undefined;
88
+ /**
89
+ * Whether a migration has anything to move, as opposed to only files left in
90
+ * place. Callers use this to avoid offering a move of nothing.
91
+ */
92
+ export declare function hasMovableContent(migration: LegacyToolMigration): boolean;
93
+ /**
94
+ * Explains why a consent-gated move is being offered, in the user's terms.
95
+ * Keyed by tool so the reason is specific rather than a generic "files moved".
96
+ */
97
+ export declare function legacyMigrationNotice(migration: LegacyToolMigration): string;
98
+ /**
99
+ * Scans installed workflow files across all detected tools and returns
100
+ * the union of installed workflow IDs.
101
+ */
102
+ export declare function scanInstalledWorkflows(projectPath: string, tools: AIToolOption[], view?: FileView): string[];
103
+ /**
104
+ * Performs one-time migration if the global config does not yet have a profile field.
105
+ * Called by both init and update before profile resolution.
106
+ *
107
+ * - If no profile field exists and workflows are installed: sets profile to 'custom'
108
+ * with the detected workflows, preserving the user's existing setup.
109
+ * - If no profile field exists and no workflows are installed: no-op (defaults apply).
110
+ * - If profile field already exists: no-op.
111
+ */
112
+ export declare function computeProfileMigration(projectPath: string, tools: AIToolOption[], view?: FileView): ProfileMigration | null;
113
+ export type ProfileMigration = {
114
+ profile: Profile;
115
+ workflows: string[];
116
+ delivery?: Delivery;
117
+ };
118
+ /** The global config the one-time profile migration saves. */
119
+ export declare function applyProfileMigration(migration: ProfileMigration): GlobalConfig;
120
+ export declare function migrateIfNeeded(projectPath: string, tools: AIToolOption[]): void;
121
+ //# sourceMappingURL=migration.d.ts.map