@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,611 @@
1
+ import { spawn, execSync } from 'node:child_process';
2
+ import * as fs from 'node:fs';
3
+ import * as path from 'node:path';
4
+ import { getGlobalConfigPath, getGlobalConfig, saveGlobalConfig, } from '../core/global-config.js';
5
+ import { getNestedValue, setNestedValue, deleteNestedValue, coerceValue, formatValueYaml, validateConfigKeyPath, validateConfig, DEFAULT_CONFIG, } from '../core/config-schema.js';
6
+ import { CORE_WORKFLOWS, ALL_WORKFLOWS, getProfileWorkflows } from '../core/profiles.js';
7
+ import { PSCODE_DIR_NAME } from '../core/config.js';
8
+ import { hasProjectConfigDrift } from '../core/profile-sync-drift.js';
9
+ import { findWorkspaceRoot, hasWorkspaceSkillProfileDrift, readOptionalWorkspaceViewState, } from '../core/workspace/index.js';
10
+ const WORKFLOW_PROMPT_META = {
11
+ propose: {
12
+ name: 'Propose change',
13
+ description: 'Create proposal, design, and tasks from a request',
14
+ },
15
+ explore: {
16
+ name: 'Explore ideas',
17
+ description: 'Investigate a problem before implementation',
18
+ },
19
+ new: {
20
+ name: 'New change',
21
+ description: 'Create a new change scaffold quickly',
22
+ },
23
+ continue: {
24
+ name: 'Continue change',
25
+ description: 'Resume work on an existing change',
26
+ },
27
+ apply: {
28
+ name: 'Apply tasks',
29
+ description: 'Implement tasks from the current change',
30
+ },
31
+ ff: {
32
+ name: 'Fast-forward',
33
+ description: 'Run a faster implementation workflow',
34
+ },
35
+ sync: {
36
+ name: 'Sync specs',
37
+ description: 'Sync change artifacts with specs',
38
+ },
39
+ archive: {
40
+ name: 'Archive change',
41
+ description: 'Finalize and archive a completed change',
42
+ },
43
+ 'bulk-archive': {
44
+ name: 'Bulk archive',
45
+ description: 'Archive multiple completed changes together',
46
+ },
47
+ verify: {
48
+ name: 'Verify change',
49
+ description: 'Run verification checks against a change',
50
+ },
51
+ onboard: {
52
+ name: 'Onboard',
53
+ description: 'Guided onboarding flow for Pscode',
54
+ },
55
+ };
56
+ function isPromptCancellationError(error) {
57
+ return (error instanceof Error &&
58
+ (error.name === 'ExitPromptError' || error.message.includes('force closed the prompt with SIGINT')));
59
+ }
60
+ /**
61
+ * Resolve the effective current profile state from global config defaults.
62
+ */
63
+ export function resolveCurrentProfileState(config) {
64
+ const profile = config.profile || 'core';
65
+ const delivery = config.delivery || 'both';
66
+ const workflows = [
67
+ ...getProfileWorkflows(profile, config.workflows ? [...config.workflows] : undefined),
68
+ ];
69
+ return { profile, delivery, workflows };
70
+ }
71
+ /**
72
+ * Derive profile type from selected workflows.
73
+ */
74
+ export function deriveProfileFromWorkflowSelection(selectedWorkflows) {
75
+ const isCoreMatch = selectedWorkflows.length === CORE_WORKFLOWS.length &&
76
+ CORE_WORKFLOWS.every((w) => selectedWorkflows.includes(w));
77
+ return isCoreMatch ? 'core' : 'custom';
78
+ }
79
+ /**
80
+ * Format a compact workflow summary for the profile header.
81
+ */
82
+ export function formatWorkflowSummary(workflows, profile) {
83
+ return `${workflows.length} selected (${profile})`;
84
+ }
85
+ function stableWorkflowOrder(workflows) {
86
+ const seen = new Set();
87
+ const ordered = [];
88
+ for (const workflow of ALL_WORKFLOWS) {
89
+ if (workflows.includes(workflow) && !seen.has(workflow)) {
90
+ ordered.push(workflow);
91
+ seen.add(workflow);
92
+ }
93
+ }
94
+ const extras = workflows.filter((w) => !ALL_WORKFLOWS.includes(w));
95
+ extras.sort();
96
+ for (const extra of extras) {
97
+ if (!seen.has(extra)) {
98
+ ordered.push(extra);
99
+ seen.add(extra);
100
+ }
101
+ }
102
+ return ordered;
103
+ }
104
+ /**
105
+ * Build a user-facing diff summary between two profile states.
106
+ */
107
+ export function diffProfileState(before, after) {
108
+ const lines = [];
109
+ if (before.delivery !== after.delivery) {
110
+ lines.push(`delivery: ${before.delivery} -> ${after.delivery}`);
111
+ }
112
+ if (before.profile !== after.profile) {
113
+ lines.push(`profile: ${before.profile} -> ${after.profile}`);
114
+ }
115
+ const beforeOrdered = stableWorkflowOrder(before.workflows);
116
+ const afterOrdered = stableWorkflowOrder(after.workflows);
117
+ const beforeSet = new Set(beforeOrdered);
118
+ const afterSet = new Set(afterOrdered);
119
+ const added = afterOrdered.filter((w) => !beforeSet.has(w));
120
+ const removed = beforeOrdered.filter((w) => !afterSet.has(w));
121
+ if (added.length > 0 || removed.length > 0) {
122
+ const tokens = [];
123
+ if (added.length > 0) {
124
+ tokens.push(`added ${added.join(', ')}`);
125
+ }
126
+ if (removed.length > 0) {
127
+ tokens.push(`removed ${removed.join(', ')}`);
128
+ }
129
+ lines.push(`workflows: ${tokens.join('; ')}`);
130
+ }
131
+ return {
132
+ hasChanges: lines.length > 0,
133
+ lines,
134
+ };
135
+ }
136
+ async function resolveWorkspaceConfigProfileContext(cwd = process.cwd()) {
137
+ const workspaceRoot = await findWorkspaceRoot(cwd);
138
+ if (!workspaceRoot) {
139
+ return null;
140
+ }
141
+ return {
142
+ root: workspaceRoot,
143
+ commandCwd: cwd,
144
+ };
145
+ }
146
+ function maybeWarnProjectConfigDrift(projectDir, state, colorize) {
147
+ const pscodeDir = path.join(projectDir, PSCODE_DIR_NAME);
148
+ if (!fs.existsSync(pscodeDir)) {
149
+ return;
150
+ }
151
+ if (!hasProjectConfigDrift(projectDir, state.workflows, state.delivery)) {
152
+ return;
153
+ }
154
+ console.log(colorize('Warning: Global config is not applied to this project. Run `pscode update` to sync.'));
155
+ }
156
+ async function maybeWarnConfigDrift(state, colorize) {
157
+ const workspaceContext = await resolveWorkspaceConfigProfileContext();
158
+ if (workspaceContext) {
159
+ let viewState = null;
160
+ try {
161
+ viewState = await readOptionalWorkspaceViewState(workspaceContext.root);
162
+ }
163
+ catch {
164
+ return;
165
+ }
166
+ if (hasWorkspaceSkillProfileDrift(viewState)) {
167
+ console.log(colorize('Warning: Workspace-local agent skills are out of sync with the active global profile. Run `pscode workspace update` to sync.'));
168
+ }
169
+ return;
170
+ }
171
+ maybeWarnProjectConfigDrift(process.cwd(), state, colorize);
172
+ }
173
+ function printConfigProfileApplyGuidance(workspaceContext) {
174
+ if (workspaceContext) {
175
+ console.log('Config updated. Run `pscode workspace update` to apply it to workspace-local skills.');
176
+ return;
177
+ }
178
+ console.log('Config updated. Run `pscode update` in your projects to apply.');
179
+ }
180
+ /**
181
+ * Register the config command and all its subcommands.
182
+ *
183
+ * @param program - The Commander program instance
184
+ */
185
+ export function registerConfigCommand(program) {
186
+ const configCmd = program
187
+ .command('config')
188
+ .description('View and modify global Pscode configuration')
189
+ .option('--scope <scope>', 'Config scope (only "global" supported currently)')
190
+ .hook('preAction', (thisCommand) => {
191
+ const opts = thisCommand.opts();
192
+ if (opts.scope && opts.scope !== 'global') {
193
+ console.error('Error: Project-local config is not yet implemented');
194
+ process.exit(1);
195
+ }
196
+ });
197
+ // config path
198
+ configCmd
199
+ .command('path')
200
+ .description('Show config file location')
201
+ .action(() => {
202
+ console.log(getGlobalConfigPath());
203
+ });
204
+ // config list
205
+ configCmd
206
+ .command('list')
207
+ .description('Show all current settings')
208
+ .option('--json', 'Output as JSON')
209
+ .action((options) => {
210
+ const config = getGlobalConfig();
211
+ if (options.json) {
212
+ console.log(JSON.stringify(config, null, 2));
213
+ }
214
+ else {
215
+ // Read raw config to determine which values are explicit vs defaults
216
+ const configPath = getGlobalConfigPath();
217
+ let rawConfig = {};
218
+ try {
219
+ if (fs.existsSync(configPath)) {
220
+ rawConfig = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
221
+ }
222
+ }
223
+ catch {
224
+ // If reading fails, treat all as defaults
225
+ }
226
+ console.log(formatValueYaml(config));
227
+ // Annotate profile settings
228
+ const profileSource = rawConfig.profile !== undefined ? '(explicit)' : '(default)';
229
+ const deliverySource = rawConfig.delivery !== undefined ? '(explicit)' : '(default)';
230
+ console.log(`\nProfile settings:`);
231
+ console.log(` profile: ${config.profile} ${profileSource}`);
232
+ console.log(` delivery: ${config.delivery} ${deliverySource}`);
233
+ if (config.profile === 'core') {
234
+ console.log(` workflows: ${CORE_WORKFLOWS.join(', ')} (from core profile)`);
235
+ }
236
+ else if (config.workflows && config.workflows.length > 0) {
237
+ console.log(` workflows: ${config.workflows.join(', ')} (explicit)`);
238
+ }
239
+ else {
240
+ console.log(` workflows: (none)`);
241
+ }
242
+ }
243
+ });
244
+ // config get
245
+ configCmd
246
+ .command('get <key>')
247
+ .description('Get a specific value (raw, scriptable)')
248
+ .action((key) => {
249
+ const config = getGlobalConfig();
250
+ const value = getNestedValue(config, key);
251
+ if (value === undefined) {
252
+ process.exitCode = 1;
253
+ return;
254
+ }
255
+ if (typeof value === 'object' && value !== null) {
256
+ console.log(JSON.stringify(value));
257
+ }
258
+ else {
259
+ console.log(String(value));
260
+ }
261
+ });
262
+ // config set
263
+ configCmd
264
+ .command('set <key> <value>')
265
+ .description('Set a value (auto-coerce types)')
266
+ .option('--string', 'Force value to be stored as string')
267
+ .option('--allow-unknown', 'Allow setting unknown keys')
268
+ .action((key, value, options) => {
269
+ const allowUnknown = Boolean(options.allowUnknown);
270
+ const keyValidation = validateConfigKeyPath(key);
271
+ if (!keyValidation.valid && !allowUnknown) {
272
+ const reason = keyValidation.reason ? ` ${keyValidation.reason}.` : '';
273
+ console.error(`Error: Invalid configuration key "${key}".${reason}`);
274
+ console.error('Use "pscode config list" to see available keys.');
275
+ console.error('Pass --allow-unknown to bypass this check.');
276
+ process.exitCode = 1;
277
+ return;
278
+ }
279
+ const config = getGlobalConfig();
280
+ const coercedValue = coerceValue(value, options.string || false);
281
+ // Create a copy to validate before saving
282
+ const newConfig = JSON.parse(JSON.stringify(config));
283
+ setNestedValue(newConfig, key, coercedValue);
284
+ // Validate the new config
285
+ const validation = validateConfig(newConfig);
286
+ if (!validation.success) {
287
+ console.error(`Error: Invalid configuration - ${validation.error}`);
288
+ process.exitCode = 1;
289
+ return;
290
+ }
291
+ // Apply changes and save
292
+ setNestedValue(config, key, coercedValue);
293
+ saveGlobalConfig(config);
294
+ const displayValue = typeof coercedValue === 'string' ? `"${coercedValue}"` : String(coercedValue);
295
+ console.log(`Set ${key} = ${displayValue}`);
296
+ });
297
+ // config unset
298
+ configCmd
299
+ .command('unset <key>')
300
+ .description('Remove a key (revert to default)')
301
+ .action((key) => {
302
+ const config = getGlobalConfig();
303
+ const existed = deleteNestedValue(config, key);
304
+ if (existed) {
305
+ saveGlobalConfig(config);
306
+ console.log(`Unset ${key} (reverted to default)`);
307
+ }
308
+ else {
309
+ console.log(`Key "${key}" was not set`);
310
+ }
311
+ });
312
+ // config reset
313
+ configCmd
314
+ .command('reset')
315
+ .description('Reset configuration to defaults')
316
+ .option('--all', 'Reset all configuration (required)')
317
+ .option('-y, --yes', 'Skip confirmation prompts')
318
+ .action(async (options) => {
319
+ if (!options.all) {
320
+ console.error('Error: --all flag is required for reset');
321
+ console.error('Usage: pscode config reset --all [-y]');
322
+ process.exitCode = 1;
323
+ return;
324
+ }
325
+ if (!options.yes) {
326
+ const { confirm } = await import('@inquirer/prompts');
327
+ let confirmed;
328
+ try {
329
+ confirmed = await confirm({
330
+ message: 'Reset all configuration to defaults?',
331
+ default: false,
332
+ });
333
+ }
334
+ catch (error) {
335
+ if (isPromptCancellationError(error)) {
336
+ console.log('Reset cancelled.');
337
+ process.exitCode = 130;
338
+ return;
339
+ }
340
+ throw error;
341
+ }
342
+ if (!confirmed) {
343
+ console.log('Reset cancelled.');
344
+ return;
345
+ }
346
+ }
347
+ saveGlobalConfig({ ...DEFAULT_CONFIG });
348
+ console.log('Configuration reset to defaults');
349
+ });
350
+ // config edit
351
+ configCmd
352
+ .command('edit')
353
+ .description('Open config in $EDITOR')
354
+ .action(async () => {
355
+ const editor = process.env.EDITOR || process.env.VISUAL;
356
+ if (!editor) {
357
+ console.error('Error: No editor configured');
358
+ console.error('Set the EDITOR or VISUAL environment variable to your preferred editor');
359
+ console.error('Example: export EDITOR=vim');
360
+ process.exitCode = 1;
361
+ return;
362
+ }
363
+ const configPath = getGlobalConfigPath();
364
+ // Ensure config file exists with defaults
365
+ if (!fs.existsSync(configPath)) {
366
+ saveGlobalConfig({ ...DEFAULT_CONFIG });
367
+ }
368
+ // Spawn editor and wait for it to close
369
+ // Avoid shell parsing to correctly handle paths with spaces in both
370
+ // the editor path and config path
371
+ const child = spawn(editor, [configPath], {
372
+ stdio: 'inherit',
373
+ shell: false,
374
+ });
375
+ await new Promise((resolve, reject) => {
376
+ child.on('close', (code) => {
377
+ if (code === 0) {
378
+ resolve();
379
+ }
380
+ else {
381
+ reject(new Error(`Editor exited with code ${code}`));
382
+ }
383
+ });
384
+ child.on('error', reject);
385
+ });
386
+ try {
387
+ const rawConfig = fs.readFileSync(configPath, 'utf-8');
388
+ const parsedConfig = JSON.parse(rawConfig);
389
+ const validation = validateConfig(parsedConfig);
390
+ if (!validation.success) {
391
+ console.error(`Error: Invalid configuration - ${validation.error}`);
392
+ process.exitCode = 1;
393
+ }
394
+ }
395
+ catch (error) {
396
+ if (error.code === 'ENOENT') {
397
+ console.error(`Error: Config file not found at ${configPath}`);
398
+ }
399
+ else if (error instanceof SyntaxError) {
400
+ console.error(`Error: Invalid JSON in ${configPath}`);
401
+ console.error(error.message);
402
+ }
403
+ else {
404
+ console.error(`Error: Unable to validate configuration - ${error instanceof Error ? error.message : String(error)}`);
405
+ }
406
+ process.exitCode = 1;
407
+ }
408
+ });
409
+ // config profile [preset]
410
+ configCmd
411
+ .command('profile [preset]')
412
+ .description('Configure workflow profile (interactive picker or preset shortcut)')
413
+ .action(async (preset) => {
414
+ // Preset shortcut: `pscode config profile core`
415
+ if (preset === 'core') {
416
+ const config = getGlobalConfig();
417
+ config.profile = 'core';
418
+ config.workflows = [...CORE_WORKFLOWS];
419
+ // Preserve delivery setting
420
+ saveGlobalConfig(config);
421
+ const workspaceContext = await resolveWorkspaceConfigProfileContext();
422
+ printConfigProfileApplyGuidance(workspaceContext);
423
+ return;
424
+ }
425
+ if (preset) {
426
+ console.error(`Error: Unknown profile preset "${preset}". Available presets: core`);
427
+ process.exitCode = 1;
428
+ return;
429
+ }
430
+ // Non-interactive check
431
+ if (!process.stdout.isTTY) {
432
+ console.error('Interactive mode required. Use `pscode config profile core` or set config via environment/flags.');
433
+ process.exitCode = 1;
434
+ return;
435
+ }
436
+ // Interactive picker
437
+ const { select, checkbox, confirm } = await import('@inquirer/prompts');
438
+ const chalk = (await import('chalk')).default;
439
+ try {
440
+ const config = getGlobalConfig();
441
+ const currentState = resolveCurrentProfileState(config);
442
+ console.log(chalk.bold('\nCurrent profile settings'));
443
+ console.log(` Delivery: ${currentState.delivery}`);
444
+ console.log(` Workflows: ${formatWorkflowSummary(currentState.workflows, currentState.profile)}`);
445
+ console.log(chalk.dim(' Delivery = where workflows are installed (skills, commands, or both)'));
446
+ console.log(chalk.dim(' Workflows = which actions are available (propose, explore, apply, etc.)'));
447
+ console.log();
448
+ const action = await select({
449
+ message: 'What do you want to configure?',
450
+ choices: [
451
+ {
452
+ value: 'both',
453
+ name: 'Delivery and workflows',
454
+ description: 'Update install mode and available actions together',
455
+ },
456
+ {
457
+ value: 'delivery',
458
+ name: 'Delivery only',
459
+ description: 'Change where workflows are installed',
460
+ },
461
+ {
462
+ value: 'workflows',
463
+ name: 'Workflows only',
464
+ description: 'Change which workflow actions are available',
465
+ },
466
+ {
467
+ value: 'keep',
468
+ name: 'Keep current settings (exit)',
469
+ description: 'Leave configuration unchanged and exit',
470
+ },
471
+ ],
472
+ });
473
+ if (action === 'keep') {
474
+ console.log('No config changes.');
475
+ await maybeWarnConfigDrift(currentState, chalk.yellow);
476
+ return;
477
+ }
478
+ const nextState = {
479
+ profile: currentState.profile,
480
+ delivery: currentState.delivery,
481
+ workflows: [...currentState.workflows],
482
+ };
483
+ if (action === 'both' || action === 'delivery') {
484
+ const deliveryChoices = [
485
+ {
486
+ value: 'both',
487
+ name: 'Both (skills + commands)',
488
+ description: 'Install workflows as both skills and slash commands',
489
+ },
490
+ {
491
+ value: 'skills',
492
+ name: 'Skills only',
493
+ description: 'Install workflows only as skills',
494
+ },
495
+ {
496
+ value: 'commands',
497
+ name: 'Commands only',
498
+ description: 'Install workflows only as slash commands',
499
+ },
500
+ ];
501
+ for (const choice of deliveryChoices) {
502
+ if (choice.value === currentState.delivery) {
503
+ choice.name += ' [current]';
504
+ }
505
+ }
506
+ nextState.delivery = await select({
507
+ message: 'Delivery mode (how workflows are installed):',
508
+ choices: deliveryChoices,
509
+ default: currentState.delivery,
510
+ });
511
+ }
512
+ if (action === 'both' || action === 'workflows') {
513
+ const formatWorkflowChoice = (workflow) => {
514
+ const metadata = WORKFLOW_PROMPT_META[workflow] ?? {
515
+ name: workflow,
516
+ description: `Workflow: ${workflow}`,
517
+ };
518
+ return {
519
+ value: workflow,
520
+ name: metadata.name,
521
+ description: metadata.description,
522
+ short: metadata.name,
523
+ checked: currentState.workflows.includes(workflow),
524
+ };
525
+ };
526
+ const selectedWorkflows = await checkbox({
527
+ message: 'Select workflows to make available:',
528
+ instructions: 'Space to toggle, Enter to confirm',
529
+ pageSize: ALL_WORKFLOWS.length,
530
+ theme: {
531
+ icon: {
532
+ checked: '[x]',
533
+ unchecked: '[ ]',
534
+ },
535
+ },
536
+ choices: ALL_WORKFLOWS.map(formatWorkflowChoice),
537
+ });
538
+ nextState.workflows = selectedWorkflows;
539
+ nextState.profile = deriveProfileFromWorkflowSelection(selectedWorkflows);
540
+ }
541
+ const diff = diffProfileState(currentState, nextState);
542
+ if (!diff.hasChanges) {
543
+ console.log('No config changes.');
544
+ await maybeWarnConfigDrift(nextState, chalk.yellow);
545
+ return;
546
+ }
547
+ console.log(chalk.bold('\nConfig changes:'));
548
+ for (const line of diff.lines) {
549
+ console.log(` ${line}`);
550
+ }
551
+ console.log();
552
+ config.profile = nextState.profile;
553
+ config.delivery = nextState.delivery;
554
+ config.workflows = nextState.workflows;
555
+ saveGlobalConfig(config);
556
+ const workspaceContext = await resolveWorkspaceConfigProfileContext();
557
+ if (workspaceContext) {
558
+ const applyNow = await confirm({
559
+ message: 'Apply changes to this workspace now?',
560
+ default: true,
561
+ });
562
+ if (applyNow) {
563
+ try {
564
+ execSync('npx pscode workspace update', {
565
+ stdio: 'inherit',
566
+ cwd: workspaceContext.commandCwd,
567
+ });
568
+ console.log('Run `pscode workspace update` in your other workspaces to apply.');
569
+ }
570
+ catch {
571
+ console.error('`pscode workspace update` failed. Please run it manually to apply the profile changes.');
572
+ process.exitCode = 1;
573
+ }
574
+ return;
575
+ }
576
+ printConfigProfileApplyGuidance(workspaceContext);
577
+ return;
578
+ }
579
+ // Check if inside an Pscode project
580
+ const projectDir = process.cwd();
581
+ const pscodeDir = path.join(projectDir, PSCODE_DIR_NAME);
582
+ if (fs.existsSync(pscodeDir)) {
583
+ const applyNow = await confirm({
584
+ message: 'Apply changes to this project now?',
585
+ default: true,
586
+ });
587
+ if (applyNow) {
588
+ try {
589
+ execSync('npx pscode update', { stdio: 'inherit', cwd: projectDir });
590
+ console.log('Run `pscode update` in your other projects to apply.');
591
+ }
592
+ catch {
593
+ console.error('`pscode update` failed. Please run it manually to apply the profile changes.');
594
+ process.exitCode = 1;
595
+ }
596
+ return;
597
+ }
598
+ }
599
+ printConfigProfileApplyGuidance(null);
600
+ }
601
+ catch (error) {
602
+ if (isPromptCancellationError(error)) {
603
+ console.log('Config profile cancelled.');
604
+ process.exitCode = 130;
605
+ return;
606
+ }
607
+ throw error;
608
+ }
609
+ });
610
+ }
611
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare function registerContextStoreCommand(program: Command): void;
3
+ //# sourceMappingURL=context-store.d.ts.map