@thiagodiogo/pscode 1.0.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 (337) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +142 -0
  3. package/bin/pscode.js +5 -0
  4. package/dist/cli/index.d.ts +5 -0
  5. package/dist/cli/index.js +526 -0
  6. package/dist/commands/change.d.ts +35 -0
  7. package/dist/commands/change.js +277 -0
  8. package/dist/commands/completion.d.ts +72 -0
  9. package/dist/commands/completion.js +264 -0
  10. package/dist/commands/config.d.ts +36 -0
  11. package/dist/commands/config.js +611 -0
  12. package/dist/commands/context-store.d.ts +3 -0
  13. package/dist/commands/context-store.js +282 -0
  14. package/dist/commands/feedback.d.ts +9 -0
  15. package/dist/commands/feedback.js +183 -0
  16. package/dist/commands/initiative.d.ts +13 -0
  17. package/dist/commands/initiative.js +318 -0
  18. package/dist/commands/schema.d.ts +6 -0
  19. package/dist/commands/schema.js +869 -0
  20. package/dist/commands/show.d.ts +14 -0
  21. package/dist/commands/show.js +132 -0
  22. package/dist/commands/spec.d.ts +15 -0
  23. package/dist/commands/spec.js +225 -0
  24. package/dist/commands/validate.d.ts +24 -0
  25. package/dist/commands/validate.js +294 -0
  26. package/dist/commands/workflow/index.d.ts +19 -0
  27. package/dist/commands/workflow/index.js +13 -0
  28. package/dist/commands/workflow/initiative-link.d.ts +24 -0
  29. package/dist/commands/workflow/initiative-link.js +47 -0
  30. package/dist/commands/workflow/instructions.d.ts +29 -0
  31. package/dist/commands/workflow/instructions.js +344 -0
  32. package/dist/commands/workflow/new-change.d.ts +17 -0
  33. package/dist/commands/workflow/new-change.js +141 -0
  34. package/dist/commands/workflow/schemas.d.ts +10 -0
  35. package/dist/commands/workflow/schemas.js +34 -0
  36. package/dist/commands/workflow/set-change.d.ts +13 -0
  37. package/dist/commands/workflow/set-change.js +87 -0
  38. package/dist/commands/workflow/shared.d.ts +59 -0
  39. package/dist/commands/workflow/shared.js +116 -0
  40. package/dist/commands/workflow/status.d.ts +14 -0
  41. package/dist/commands/workflow/status.js +90 -0
  42. package/dist/commands/workflow/templates.d.ts +16 -0
  43. package/dist/commands/workflow/templates.js +69 -0
  44. package/dist/commands/workspace/context-status.d.ts +4 -0
  45. package/dist/commands/workspace/context-status.js +59 -0
  46. package/dist/commands/workspace/open-view.d.ts +62 -0
  47. package/dist/commands/workspace/open-view.js +228 -0
  48. package/dist/commands/workspace/open.d.ts +37 -0
  49. package/dist/commands/workspace/open.js +102 -0
  50. package/dist/commands/workspace/opener-selection.d.ts +11 -0
  51. package/dist/commands/workspace/opener-selection.js +93 -0
  52. package/dist/commands/workspace/operations.d.ts +28 -0
  53. package/dist/commands/workspace/operations.js +543 -0
  54. package/dist/commands/workspace/prompt-theme.d.ts +29 -0
  55. package/dist/commands/workspace/prompt-theme.js +24 -0
  56. package/dist/commands/workspace/registration.d.ts +13 -0
  57. package/dist/commands/workspace/registration.js +84 -0
  58. package/dist/commands/workspace/selection.d.ts +6 -0
  59. package/dist/commands/workspace/selection.js +122 -0
  60. package/dist/commands/workspace/types.d.ts +103 -0
  61. package/dist/commands/workspace/types.js +36 -0
  62. package/dist/commands/workspace.d.ts +6 -0
  63. package/dist/commands/workspace.js +678 -0
  64. package/dist/core/archive.d.ts +11 -0
  65. package/dist/core/archive.js +318 -0
  66. package/dist/core/artifact-graph/graph.d.ts +56 -0
  67. package/dist/core/artifact-graph/graph.js +141 -0
  68. package/dist/core/artifact-graph/index.d.ts +9 -0
  69. package/dist/core/artifact-graph/index.js +14 -0
  70. package/dist/core/artifact-graph/instruction-loader.d.ts +183 -0
  71. package/dist/core/artifact-graph/instruction-loader.js +256 -0
  72. package/dist/core/artifact-graph/outputs.d.ts +14 -0
  73. package/dist/core/artifact-graph/outputs.js +39 -0
  74. package/dist/core/artifact-graph/resolver.d.ts +81 -0
  75. package/dist/core/artifact-graph/resolver.js +257 -0
  76. package/dist/core/artifact-graph/schema.d.ts +13 -0
  77. package/dist/core/artifact-graph/schema.js +108 -0
  78. package/dist/core/artifact-graph/state.d.ts +12 -0
  79. package/dist/core/artifact-graph/state.js +31 -0
  80. package/dist/core/artifact-graph/types.d.ts +40 -0
  81. package/dist/core/artifact-graph/types.js +29 -0
  82. package/dist/core/available-tools.d.ts +17 -0
  83. package/dist/core/available-tools.js +43 -0
  84. package/dist/core/change-metadata/index.d.ts +2 -0
  85. package/dist/core/change-metadata/index.js +2 -0
  86. package/dist/core/change-metadata/schema.d.ts +18 -0
  87. package/dist/core/change-metadata/schema.js +28 -0
  88. package/dist/core/change-status-policy.d.ts +50 -0
  89. package/dist/core/change-status-policy.js +70 -0
  90. package/dist/core/collections/index.d.ts +3 -0
  91. package/dist/core/collections/index.js +3 -0
  92. package/dist/core/collections/initiatives/collection.d.ts +4 -0
  93. package/dist/core/collections/initiatives/collection.js +17 -0
  94. package/dist/core/collections/initiatives/index.d.ts +6 -0
  95. package/dist/core/collections/initiatives/index.js +6 -0
  96. package/dist/core/collections/initiatives/operations.d.ts +49 -0
  97. package/dist/core/collections/initiatives/operations.js +175 -0
  98. package/dist/core/collections/initiatives/resolution.d.ts +87 -0
  99. package/dist/core/collections/initiatives/resolution.js +374 -0
  100. package/dist/core/collections/initiatives/schema.d.ts +41 -0
  101. package/dist/core/collections/initiatives/schema.js +134 -0
  102. package/dist/core/collections/initiatives/templates.d.ts +12 -0
  103. package/dist/core/collections/initiatives/templates.js +90 -0
  104. package/dist/core/collections/runtime.d.ts +46 -0
  105. package/dist/core/collections/runtime.js +194 -0
  106. package/dist/core/command-generation/adapters/claude.d.ts +13 -0
  107. package/dist/core/command-generation/adapters/claude.js +50 -0
  108. package/dist/core/command-generation/adapters/codex.d.ts +16 -0
  109. package/dist/core/command-generation/adapters/codex.js +39 -0
  110. package/dist/core/command-generation/adapters/cursor.d.ts +14 -0
  111. package/dist/core/command-generation/adapters/cursor.js +44 -0
  112. package/dist/core/command-generation/adapters/gemini.d.ts +13 -0
  113. package/dist/core/command-generation/adapters/gemini.js +26 -0
  114. package/dist/core/command-generation/adapters/github-copilot.d.ts +13 -0
  115. package/dist/core/command-generation/adapters/github-copilot.js +26 -0
  116. package/dist/core/command-generation/adapters/index.d.ts +11 -0
  117. package/dist/core/command-generation/adapters/index.js +11 -0
  118. package/dist/core/command-generation/generator.d.ts +21 -0
  119. package/dist/core/command-generation/generator.js +27 -0
  120. package/dist/core/command-generation/index.d.ts +22 -0
  121. package/dist/core/command-generation/index.js +24 -0
  122. package/dist/core/command-generation/registry.d.ts +35 -0
  123. package/dist/core/command-generation/registry.js +55 -0
  124. package/dist/core/command-generation/types.d.ts +56 -0
  125. package/dist/core/command-generation/types.js +8 -0
  126. package/dist/core/completions/command-registry.d.ts +3 -0
  127. package/dist/core/completions/command-registry.js +939 -0
  128. package/dist/core/completions/completion-provider.d.ts +71 -0
  129. package/dist/core/completions/completion-provider.js +129 -0
  130. package/dist/core/completions/factory.d.ts +64 -0
  131. package/dist/core/completions/factory.js +75 -0
  132. package/dist/core/completions/generators/bash-generator.d.ts +35 -0
  133. package/dist/core/completions/generators/bash-generator.js +230 -0
  134. package/dist/core/completions/generators/fish-generator.d.ts +32 -0
  135. package/dist/core/completions/generators/fish-generator.js +160 -0
  136. package/dist/core/completions/generators/powershell-generator.d.ts +36 -0
  137. package/dist/core/completions/generators/powershell-generator.js +266 -0
  138. package/dist/core/completions/generators/zsh-generator.d.ts +47 -0
  139. package/dist/core/completions/generators/zsh-generator.js +274 -0
  140. package/dist/core/completions/installers/bash-installer.d.ts +87 -0
  141. package/dist/core/completions/installers/bash-installer.js +318 -0
  142. package/dist/core/completions/installers/fish-installer.d.ts +43 -0
  143. package/dist/core/completions/installers/fish-installer.js +143 -0
  144. package/dist/core/completions/installers/powershell-installer.d.ts +102 -0
  145. package/dist/core/completions/installers/powershell-installer.js +387 -0
  146. package/dist/core/completions/installers/zsh-installer.d.ts +117 -0
  147. package/dist/core/completions/installers/zsh-installer.js +421 -0
  148. package/dist/core/completions/shared-flags.d.ts +12 -0
  149. package/dist/core/completions/shared-flags.js +28 -0
  150. package/dist/core/completions/templates/bash-templates.d.ts +6 -0
  151. package/dist/core/completions/templates/bash-templates.js +30 -0
  152. package/dist/core/completions/templates/fish-templates.d.ts +7 -0
  153. package/dist/core/completions/templates/fish-templates.js +45 -0
  154. package/dist/core/completions/templates/powershell-templates.d.ts +6 -0
  155. package/dist/core/completions/templates/powershell-templates.js +34 -0
  156. package/dist/core/completions/templates/zsh-templates.d.ts +6 -0
  157. package/dist/core/completions/templates/zsh-templates.js +45 -0
  158. package/dist/core/completions/types.d.ts +101 -0
  159. package/dist/core/completions/types.js +2 -0
  160. package/dist/core/config-prompts.d.ts +9 -0
  161. package/dist/core/config-prompts.js +34 -0
  162. package/dist/core/config-schema.d.ts +86 -0
  163. package/dist/core/config-schema.js +213 -0
  164. package/dist/core/config.d.ts +18 -0
  165. package/dist/core/config.js +13 -0
  166. package/dist/core/context-store/binding.d.ts +53 -0
  167. package/dist/core/context-store/binding.js +197 -0
  168. package/dist/core/context-store/errors.d.ts +20 -0
  169. package/dist/core/context-store/errors.js +22 -0
  170. package/dist/core/context-store/foundation.d.ts +54 -0
  171. package/dist/core/context-store/foundation.js +318 -0
  172. package/dist/core/context-store/index.d.ts +6 -0
  173. package/dist/core/context-store/index.js +6 -0
  174. package/dist/core/context-store/operations.d.ts +62 -0
  175. package/dist/core/context-store/operations.js +352 -0
  176. package/dist/core/context-store/registry.d.ts +35 -0
  177. package/dist/core/context-store/registry.js +158 -0
  178. package/dist/core/converters/json-converter.d.ts +6 -0
  179. package/dist/core/converters/json-converter.js +51 -0
  180. package/dist/core/global-config.d.ts +49 -0
  181. package/dist/core/global-config.js +124 -0
  182. package/dist/core/index.d.ts +6 -0
  183. package/dist/core/index.js +7 -0
  184. package/dist/core/init.d.ts +40 -0
  185. package/dist/core/init.js +676 -0
  186. package/dist/core/legacy-cleanup.d.ts +162 -0
  187. package/dist/core/legacy-cleanup.js +489 -0
  188. package/dist/core/list.d.ts +9 -0
  189. package/dist/core/list.js +171 -0
  190. package/dist/core/migration.d.ts +23 -0
  191. package/dist/core/migration.js +108 -0
  192. package/dist/core/openspec-migration.d.ts +71 -0
  193. package/dist/core/openspec-migration.js +320 -0
  194. package/dist/core/parsers/change-parser.d.ts +13 -0
  195. package/dist/core/parsers/change-parser.js +197 -0
  196. package/dist/core/parsers/markdown-parser.d.ts +26 -0
  197. package/dist/core/parsers/markdown-parser.js +227 -0
  198. package/dist/core/parsers/requirement-blocks.d.ts +37 -0
  199. package/dist/core/parsers/requirement-blocks.js +201 -0
  200. package/dist/core/parsers/spec-structure.d.ts +9 -0
  201. package/dist/core/parsers/spec-structure.js +88 -0
  202. package/dist/core/planning-home.d.ts +21 -0
  203. package/dist/core/planning-home.js +108 -0
  204. package/dist/core/profile-sync-drift.d.ts +38 -0
  205. package/dist/core/profile-sync-drift.js +203 -0
  206. package/dist/core/profiles.d.ts +26 -0
  207. package/dist/core/profiles.js +43 -0
  208. package/dist/core/project-config.d.ts +64 -0
  209. package/dist/core/project-config.js +223 -0
  210. package/dist/core/schemas/base.schema.d.ts +13 -0
  211. package/dist/core/schemas/base.schema.js +13 -0
  212. package/dist/core/schemas/change.schema.d.ts +73 -0
  213. package/dist/core/schemas/change.schema.js +31 -0
  214. package/dist/core/schemas/index.d.ts +4 -0
  215. package/dist/core/schemas/index.js +4 -0
  216. package/dist/core/schemas/spec.schema.d.ts +18 -0
  217. package/dist/core/schemas/spec.schema.js +15 -0
  218. package/dist/core/shared/index.d.ts +8 -0
  219. package/dist/core/shared/index.js +8 -0
  220. package/dist/core/shared/skill-generation.d.ts +49 -0
  221. package/dist/core/shared/skill-generation.js +102 -0
  222. package/dist/core/shared/tool-detection.d.ts +71 -0
  223. package/dist/core/shared/tool-detection.js +158 -0
  224. package/dist/core/specs-apply.d.ts +73 -0
  225. package/dist/core/specs-apply.js +392 -0
  226. package/dist/core/styles/palette.d.ts +7 -0
  227. package/dist/core/styles/palette.js +8 -0
  228. package/dist/core/templates/index.d.ts +8 -0
  229. package/dist/core/templates/index.js +9 -0
  230. package/dist/core/templates/skill-templates.d.ts +21 -0
  231. package/dist/core/templates/skill-templates.js +21 -0
  232. package/dist/core/templates/types.d.ts +19 -0
  233. package/dist/core/templates/types.js +5 -0
  234. package/dist/core/templates/workflows/apply-change.d.ts +10 -0
  235. package/dist/core/templates/workflows/apply-change.js +287 -0
  236. package/dist/core/templates/workflows/archive-change.d.ts +10 -0
  237. package/dist/core/templates/workflows/archive-change.js +227 -0
  238. package/dist/core/templates/workflows/bulk-archive-change.d.ts +10 -0
  239. package/dist/core/templates/workflows/bulk-archive-change.js +492 -0
  240. package/dist/core/templates/workflows/continue-change.d.ts +10 -0
  241. package/dist/core/templates/workflows/continue-change.js +234 -0
  242. package/dist/core/templates/workflows/explore.d.ts +10 -0
  243. package/dist/core/templates/workflows/explore.js +755 -0
  244. package/dist/core/templates/workflows/feedback.d.ts +9 -0
  245. package/dist/core/templates/workflows/feedback.js +108 -0
  246. package/dist/core/templates/workflows/ff-change.d.ts +10 -0
  247. package/dist/core/templates/workflows/ff-change.js +200 -0
  248. package/dist/core/templates/workflows/new-change.d.ts +10 -0
  249. package/dist/core/templates/workflows/new-change.js +143 -0
  250. package/dist/core/templates/workflows/onboard.d.ts +10 -0
  251. package/dist/core/templates/workflows/onboard.js +607 -0
  252. package/dist/core/templates/workflows/propose.d.ts +10 -0
  253. package/dist/core/templates/workflows/propose.js +347 -0
  254. package/dist/core/templates/workflows/sync-specs.d.ts +10 -0
  255. package/dist/core/templates/workflows/sync-specs.js +290 -0
  256. package/dist/core/templates/workflows/trello-draft.d.ts +12 -0
  257. package/dist/core/templates/workflows/trello-draft.js +217 -0
  258. package/dist/core/templates/workflows/trello-setup.d.ts +12 -0
  259. package/dist/core/templates/workflows/trello-setup.js +315 -0
  260. package/dist/core/templates/workflows/verify-change.d.ts +10 -0
  261. package/dist/core/templates/workflows/verify-change.js +338 -0
  262. package/dist/core/trello-config.d.ts +90 -0
  263. package/dist/core/trello-config.js +86 -0
  264. package/dist/core/trello-init-prompt.d.ts +61 -0
  265. package/dist/core/trello-init-prompt.js +180 -0
  266. package/dist/core/update.d.ts +82 -0
  267. package/dist/core/update.js +560 -0
  268. package/dist/core/validation/constants.d.ts +34 -0
  269. package/dist/core/validation/constants.js +40 -0
  270. package/dist/core/validation/types.d.ts +18 -0
  271. package/dist/core/validation/types.js +2 -0
  272. package/dist/core/validation/validator.d.ts +33 -0
  273. package/dist/core/validation/validator.js +418 -0
  274. package/dist/core/view.d.ts +8 -0
  275. package/dist/core/view.js +168 -0
  276. package/dist/core/workspace/foundation.d.ts +62 -0
  277. package/dist/core/workspace/foundation.js +274 -0
  278. package/dist/core/workspace/index.d.ts +8 -0
  279. package/dist/core/workspace/index.js +8 -0
  280. package/dist/core/workspace/legacy-state.d.ts +28 -0
  281. package/dist/core/workspace/legacy-state.js +200 -0
  282. package/dist/core/workspace/link-input.d.ts +9 -0
  283. package/dist/core/workspace/link-input.js +32 -0
  284. package/dist/core/workspace/open-surface.d.ts +43 -0
  285. package/dist/core/workspace/open-surface.js +214 -0
  286. package/dist/core/workspace/openers.d.ts +21 -0
  287. package/dist/core/workspace/openers.js +119 -0
  288. package/dist/core/workspace/registry.d.ts +24 -0
  289. package/dist/core/workspace/registry.js +146 -0
  290. package/dist/core/workspace/skills.d.ts +57 -0
  291. package/dist/core/workspace/skills.js +334 -0
  292. package/dist/core/workspace/state-io.d.ts +10 -0
  293. package/dist/core/workspace/state-io.js +119 -0
  294. package/dist/index.d.ts +3 -0
  295. package/dist/index.js +3 -0
  296. package/dist/prompts/searchable-multi-select.d.ts +28 -0
  297. package/dist/prompts/searchable-multi-select.js +159 -0
  298. package/dist/telemetry/config.d.ts +38 -0
  299. package/dist/telemetry/config.js +136 -0
  300. package/dist/telemetry/index.d.ts +31 -0
  301. package/dist/telemetry/index.js +164 -0
  302. package/dist/ui/ascii-patterns.d.ts +16 -0
  303. package/dist/ui/ascii-patterns.js +133 -0
  304. package/dist/ui/welcome-screen.d.ts +10 -0
  305. package/dist/ui/welcome-screen.js +146 -0
  306. package/dist/utils/change-metadata.d.ts +54 -0
  307. package/dist/utils/change-metadata.js +141 -0
  308. package/dist/utils/change-utils.d.ts +71 -0
  309. package/dist/utils/change-utils.js +123 -0
  310. package/dist/utils/command-references.d.ts +18 -0
  311. package/dist/utils/command-references.js +20 -0
  312. package/dist/utils/file-system.d.ts +41 -0
  313. package/dist/utils/file-system.js +301 -0
  314. package/dist/utils/index.d.ts +6 -0
  315. package/dist/utils/index.js +9 -0
  316. package/dist/utils/interactive.d.ts +18 -0
  317. package/dist/utils/interactive.js +21 -0
  318. package/dist/utils/item-discovery.d.ts +4 -0
  319. package/dist/utils/item-discovery.js +72 -0
  320. package/dist/utils/match.d.ts +3 -0
  321. package/dist/utils/match.js +22 -0
  322. package/dist/utils/shell-detection.d.ts +20 -0
  323. package/dist/utils/shell-detection.js +41 -0
  324. package/dist/utils/task-progress.d.ts +8 -0
  325. package/dist/utils/task-progress.js +36 -0
  326. package/package.json +84 -0
  327. package/schemas/spec-driven/schema.yaml +153 -0
  328. package/schemas/spec-driven/templates/design.md +19 -0
  329. package/schemas/spec-driven/templates/proposal.md +23 -0
  330. package/schemas/spec-driven/templates/spec.md +8 -0
  331. package/schemas/spec-driven/templates/tasks.md +9 -0
  332. package/schemas/workspace-planning/schema.yaml +72 -0
  333. package/schemas/workspace-planning/templates/design.md +33 -0
  334. package/schemas/workspace-planning/templates/proposal.md +28 -0
  335. package/schemas/workspace-planning/templates/spec.md +9 -0
  336. package/schemas/workspace-planning/templates/tasks.md +15 -0
  337. package/scripts/postinstall.js +83 -0
@@ -0,0 +1,171 @@
1
+ import { promises as fs } from 'fs';
2
+ import path from 'path';
3
+ import { getTaskProgressForChange, formatTaskStatus } from '../utils/task-progress.js';
4
+ import { readFileSync } from 'fs';
5
+ import { join } from 'path';
6
+ import { MarkdownParser } from './parsers/markdown-parser.js';
7
+ /**
8
+ * Get the most recent modification time of any file in a directory (recursive).
9
+ * Falls back to the directory's own mtime if no files are found.
10
+ */
11
+ async function getLastModified(dirPath) {
12
+ let latest = null;
13
+ async function walk(dir) {
14
+ const entries = await fs.readdir(dir, { withFileTypes: true });
15
+ for (const entry of entries) {
16
+ const fullPath = path.join(dir, entry.name);
17
+ if (entry.isDirectory()) {
18
+ await walk(fullPath);
19
+ }
20
+ else {
21
+ const stat = await fs.stat(fullPath);
22
+ if (latest === null || stat.mtime > latest) {
23
+ latest = stat.mtime;
24
+ }
25
+ }
26
+ }
27
+ }
28
+ await walk(dirPath);
29
+ // If no files found, use the directory's own modification time
30
+ if (latest === null) {
31
+ const dirStat = await fs.stat(dirPath);
32
+ return dirStat.mtime;
33
+ }
34
+ return latest;
35
+ }
36
+ /**
37
+ * Format a date as relative time (e.g., "2 hours ago", "3 days ago")
38
+ */
39
+ function formatRelativeTime(date) {
40
+ const now = new Date();
41
+ const diffMs = now.getTime() - date.getTime();
42
+ const diffSecs = Math.floor(diffMs / 1000);
43
+ const diffMins = Math.floor(diffSecs / 60);
44
+ const diffHours = Math.floor(diffMins / 60);
45
+ const diffDays = Math.floor(diffHours / 24);
46
+ if (diffDays > 30) {
47
+ return date.toLocaleDateString();
48
+ }
49
+ else if (diffDays > 0) {
50
+ return `${diffDays}d ago`;
51
+ }
52
+ else if (diffHours > 0) {
53
+ return `${diffHours}h ago`;
54
+ }
55
+ else if (diffMins > 0) {
56
+ return `${diffMins}m ago`;
57
+ }
58
+ else {
59
+ return 'just now';
60
+ }
61
+ }
62
+ export class ListCommand {
63
+ async execute(targetPath = '.', mode = 'changes', options = {}) {
64
+ const { sort = 'recent', json = false } = options;
65
+ if (mode === 'changes') {
66
+ const changesDir = path.join(targetPath, 'pscode', 'changes');
67
+ // Check if changes directory exists
68
+ try {
69
+ await fs.access(changesDir);
70
+ }
71
+ catch {
72
+ throw new Error("No Pscode changes directory found. Run 'pscode init' first.");
73
+ }
74
+ // Get all directories in changes (excluding archive)
75
+ const entries = await fs.readdir(changesDir, { withFileTypes: true });
76
+ const changeDirs = entries
77
+ .filter(entry => entry.isDirectory() && entry.name !== 'archive')
78
+ .map(entry => entry.name);
79
+ if (changeDirs.length === 0) {
80
+ if (json) {
81
+ console.log(JSON.stringify({ changes: [] }));
82
+ }
83
+ else {
84
+ console.log('No active changes found.');
85
+ }
86
+ return;
87
+ }
88
+ // Collect information about each change
89
+ const changes = [];
90
+ for (const changeDir of changeDirs) {
91
+ const progress = await getTaskProgressForChange(changesDir, changeDir);
92
+ const changePath = path.join(changesDir, changeDir);
93
+ const lastModified = await getLastModified(changePath);
94
+ changes.push({
95
+ name: changeDir,
96
+ completedTasks: progress.completed,
97
+ totalTasks: progress.total,
98
+ lastModified
99
+ });
100
+ }
101
+ // Sort by preference (default: recent first)
102
+ if (sort === 'recent') {
103
+ changes.sort((a, b) => b.lastModified.getTime() - a.lastModified.getTime());
104
+ }
105
+ else {
106
+ changes.sort((a, b) => a.name.localeCompare(b.name));
107
+ }
108
+ // JSON output for programmatic use
109
+ if (json) {
110
+ const jsonOutput = changes.map(c => ({
111
+ name: c.name,
112
+ completedTasks: c.completedTasks,
113
+ totalTasks: c.totalTasks,
114
+ lastModified: c.lastModified.toISOString(),
115
+ status: c.totalTasks === 0 ? 'no-tasks' : c.completedTasks === c.totalTasks ? 'complete' : 'in-progress'
116
+ }));
117
+ console.log(JSON.stringify({ changes: jsonOutput }, null, 2));
118
+ return;
119
+ }
120
+ // Display results
121
+ console.log('Changes:');
122
+ const padding = ' ';
123
+ const nameWidth = Math.max(...changes.map(c => c.name.length));
124
+ for (const change of changes) {
125
+ const paddedName = change.name.padEnd(nameWidth);
126
+ const status = formatTaskStatus({ total: change.totalTasks, completed: change.completedTasks });
127
+ const timeAgo = formatRelativeTime(change.lastModified);
128
+ console.log(`${padding}${paddedName} ${status.padEnd(12)} ${timeAgo}`);
129
+ }
130
+ return;
131
+ }
132
+ // specs mode
133
+ const specsDir = path.join(targetPath, 'pscode', 'specs');
134
+ try {
135
+ await fs.access(specsDir);
136
+ }
137
+ catch {
138
+ console.log('No specs found.');
139
+ return;
140
+ }
141
+ const entries = await fs.readdir(specsDir, { withFileTypes: true });
142
+ const specDirs = entries.filter(e => e.isDirectory()).map(e => e.name);
143
+ if (specDirs.length === 0) {
144
+ console.log('No specs found.');
145
+ return;
146
+ }
147
+ const specs = [];
148
+ for (const id of specDirs) {
149
+ const specPath = join(specsDir, id, 'spec.md');
150
+ try {
151
+ const content = readFileSync(specPath, 'utf-8');
152
+ const parser = new MarkdownParser(content);
153
+ const spec = parser.parseSpec(id);
154
+ specs.push({ id, requirementCount: spec.requirements.length });
155
+ }
156
+ catch {
157
+ // If spec cannot be read or parsed, include with 0 count
158
+ specs.push({ id, requirementCount: 0 });
159
+ }
160
+ }
161
+ specs.sort((a, b) => a.id.localeCompare(b.id));
162
+ console.log('Specs:');
163
+ const padding = ' ';
164
+ const nameWidth = Math.max(...specs.map(s => s.id.length));
165
+ for (const spec of specs) {
166
+ const padded = spec.id.padEnd(nameWidth);
167
+ console.log(`${padding}${padded} requirements ${spec.requirementCount}`);
168
+ }
169
+ }
170
+ }
171
+ //# sourceMappingURL=list.js.map
@@ -0,0 +1,23 @@
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
+ /**
9
+ * Scans installed workflow files across all detected tools and returns
10
+ * the union of installed workflow IDs.
11
+ */
12
+ export declare function scanInstalledWorkflows(projectPath: string, tools: AIToolOption[]): string[];
13
+ /**
14
+ * Performs one-time migration if the global config does not yet have a profile field.
15
+ * Called by both init and update before profile resolution.
16
+ *
17
+ * - If no profile field exists and workflows are installed: sets profile to 'custom'
18
+ * with the detected workflows, preserving the user's existing setup.
19
+ * - If no profile field exists and no workflows are installed: no-op (defaults apply).
20
+ * - If profile field already exists: no-op.
21
+ */
22
+ export declare function migrateIfNeeded(projectPath: string, tools: AIToolOption[]): void;
23
+ //# sourceMappingURL=migration.d.ts.map
@@ -0,0 +1,108 @@
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 { getGlobalConfig, getGlobalConfigPath, saveGlobalConfig } from './global-config.js';
8
+ import { CommandAdapterRegistry } from './command-generation/index.js';
9
+ import { WORKFLOW_TO_SKILL_DIR } from './profile-sync-drift.js';
10
+ import { ALL_WORKFLOWS } from './profiles.js';
11
+ import path from 'path';
12
+ import * as fs from 'fs';
13
+ function scanInstalledWorkflowArtifacts(projectPath, tools) {
14
+ const installed = new Set();
15
+ let hasSkills = false;
16
+ let hasCommands = false;
17
+ for (const tool of tools) {
18
+ if (!tool.skillsDir)
19
+ continue;
20
+ const skillsDir = path.join(projectPath, tool.skillsDir, 'skills');
21
+ for (const workflowId of ALL_WORKFLOWS) {
22
+ const skillDirName = WORKFLOW_TO_SKILL_DIR[workflowId];
23
+ const skillFile = path.join(skillsDir, skillDirName, 'SKILL.md');
24
+ if (fs.existsSync(skillFile)) {
25
+ installed.add(workflowId);
26
+ hasSkills = true;
27
+ }
28
+ }
29
+ const adapter = CommandAdapterRegistry.get(tool.value);
30
+ if (!adapter)
31
+ continue;
32
+ for (const workflowId of ALL_WORKFLOWS) {
33
+ const commandPath = adapter.getFilePath(workflowId);
34
+ const fullPath = path.isAbsolute(commandPath)
35
+ ? commandPath
36
+ : path.join(projectPath, commandPath);
37
+ if (fs.existsSync(fullPath)) {
38
+ installed.add(workflowId);
39
+ hasCommands = true;
40
+ }
41
+ }
42
+ }
43
+ return {
44
+ workflows: ALL_WORKFLOWS.filter((workflowId) => installed.has(workflowId)),
45
+ hasSkills,
46
+ hasCommands,
47
+ };
48
+ }
49
+ /**
50
+ * Scans installed workflow files across all detected tools and returns
51
+ * the union of installed workflow IDs.
52
+ */
53
+ export function scanInstalledWorkflows(projectPath, tools) {
54
+ return scanInstalledWorkflowArtifacts(projectPath, tools).workflows;
55
+ }
56
+ function inferDelivery(artifacts) {
57
+ if (artifacts.hasSkills && artifacts.hasCommands) {
58
+ return 'both';
59
+ }
60
+ if (artifacts.hasCommands) {
61
+ return 'commands';
62
+ }
63
+ return 'skills';
64
+ }
65
+ /**
66
+ * Performs one-time migration if the global config does not yet have a profile field.
67
+ * Called by both init and update before profile resolution.
68
+ *
69
+ * - If no profile field exists and workflows are installed: sets profile to 'custom'
70
+ * with the detected workflows, preserving the user's existing setup.
71
+ * - If no profile field exists and no workflows are installed: no-op (defaults apply).
72
+ * - If profile field already exists: no-op.
73
+ */
74
+ export function migrateIfNeeded(projectPath, tools) {
75
+ const config = getGlobalConfig();
76
+ // Check raw config file for profile field presence
77
+ const configPath = getGlobalConfigPath();
78
+ let rawConfig = {};
79
+ try {
80
+ if (fs.existsSync(configPath)) {
81
+ rawConfig = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
82
+ }
83
+ }
84
+ catch {
85
+ return; // Can't read config, skip migration
86
+ }
87
+ // If profile is already explicitly set, no migration needed
88
+ if (rawConfig.profile !== undefined) {
89
+ return;
90
+ }
91
+ // Scan for installed workflows
92
+ const artifacts = scanInstalledWorkflowArtifacts(projectPath, tools);
93
+ const installedWorkflows = artifacts.workflows;
94
+ if (installedWorkflows.length === 0) {
95
+ // No workflows installed, new user — defaults will apply
96
+ return;
97
+ }
98
+ // Migrate: set profile to custom with detected workflows
99
+ config.profile = 'custom';
100
+ config.workflows = installedWorkflows;
101
+ if (rawConfig.delivery === undefined) {
102
+ config.delivery = inferDelivery(artifacts);
103
+ }
104
+ saveGlobalConfig(config);
105
+ console.log(`Migrated: custom profile with ${installedWorkflows.length} workflows`);
106
+ console.log("New in this version: /ps:propose. Try 'pscode config profile core' for the streamlined experience.");
107
+ }
108
+ //# sourceMappingURL=migration.js.map
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Legacy Tool → Pscode Migration
3
+ *
4
+ * Detects projects using the old "openspec" structure and migrates them
5
+ * cleanly to Pscode: deletes old skills/commands generated by openspec
6
+ * (opsx-* prefix), renames the .openspec/ folder to pscode/, and
7
+ * migrates any stale config fields.
8
+ *
9
+ * Migration is triggered automatically during `pscode init` when an
10
+ * .openspec/ directory is detected. The user is prompted to confirm before
11
+ * any changes are made.
12
+ */
13
+ export interface LegacyToolDetectionResult {
14
+ /** Whether an openspec/ or .openspec/ directory was found */
15
+ hasLegacyDir: boolean;
16
+ /** Full path to the openspec/ (or .openspec/) directory that was found */
17
+ legacyDirPath: string;
18
+ /** Directory name as it appears on disk ("openspec" or ".openspec") */
19
+ legacyDirName: string;
20
+ /** Old opsx-* skill files found across all tool dirs */
21
+ legacySkillFiles: string[];
22
+ /** Old opsx-* / openspec command files found across all tool dirs */
23
+ legacyCommandFiles: string[];
24
+ /** Whether any legacy tool artifacts were found */
25
+ hasLegacyArtifacts: boolean;
26
+ }
27
+ export interface LegacyToolMigrationResult {
28
+ /** Whether openspec/ (or .openspec/) was renamed to pscode/ */
29
+ renamedDir: boolean;
30
+ /** Whether openspec/ (or .openspec/) content was merged into an existing pscode/ */
31
+ mergedDir: boolean;
32
+ /** The directory name that was migrated ("openspec" or ".openspec") */
33
+ sourceDirName: string;
34
+ /** Skill files deleted */
35
+ deletedSkills: string[];
36
+ /** Command files/dirs deleted */
37
+ deletedCommands: string[];
38
+ /** Files copied during merge (relative to project root) */
39
+ mergedFiles: string[];
40
+ /** Errors that occurred */
41
+ errors: string[];
42
+ }
43
+ /**
44
+ * Detects legacy tool artifacts in a project.
45
+ * Checks for both "openspec/" and ".openspec/" directory names.
46
+ */
47
+ export declare function detectLegacyToolArtifacts(projectPath: string): Promise<LegacyToolDetectionResult>;
48
+ /**
49
+ * Formats a human-readable summary of what was detected.
50
+ * @param pscodeAlreadyExists - when true, shows merge instead of rename
51
+ */
52
+ export declare function formatLegacyToolDetectionSummary(detection: LegacyToolDetectionResult, pscodeAlreadyExists?: boolean): string;
53
+ /**
54
+ * Formats a summary of what was done during migration.
55
+ */
56
+ export declare function formatLegacyToolMigrationSummary(result: LegacyToolMigrationResult): string;
57
+ /**
58
+ * Runs the legacy tool → pscode migration.
59
+ * - Deletes old opsx-* skill directories
60
+ * - Deletes old openspec command files/directories
61
+ * - If pscode/ doesn't exist: renames .openspec/ → pscode/
62
+ * - If pscode/ already exists: merges changes/ and specs/ from .openspec/
63
+ * into pscode/ (existing files are never overwritten), then removes .openspec/
64
+ */
65
+ export declare function runLegacyToolMigration(projectPath: string, detection: LegacyToolDetectionResult): Promise<LegacyToolMigrationResult>;
66
+ /**
67
+ * Returns true when a `pscode/` directory already exists at the given project path.
68
+ * Used by the init command to pass the correct context to formatLegacyToolDetectionSummary.
69
+ */
70
+ export declare function pscodeDirExists(projectPath: string): Promise<boolean>;
71
+ //# sourceMappingURL=openspec-migration.d.ts.map