savepoint 1.0.3 → 1.0.6

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 (418) hide show
  1. package/package.json +10 -3
  2. package/{savepoint → savepoint.exe} +0 -0
  3. package/.claude/settings.local.json +0 -38
  4. package/.golangci.yml +0 -11
  5. package/.prettierignore +0 -4
  6. package/.savepoint/Design.md +0 -206
  7. package/.savepoint/PRD.md +0 -58
  8. package/.savepoint/config.yml +0 -27
  9. package/.savepoint/releases/v1/epics/E01-go-setup/E01-Detail.md +0 -39
  10. package/.savepoint/releases/v1/epics/E01-go-setup/tasks/T001-init-module.md +0 -42
  11. package/.savepoint/releases/v1/epics/E01-go-setup/tasks/T002-entrypoint.md +0 -23
  12. package/.savepoint/releases/v1/epics/E01-go-setup/tasks/T003-directory-structure.md +0 -24
  13. package/.savepoint/releases/v1/epics/E01-go-setup/tasks/T004-makefile.md +0 -23
  14. package/.savepoint/releases/v1/epics/E02-data-readers/E02-Detail.md +0 -61
  15. package/.savepoint/releases/v1/epics/E02-data-readers/tasks/T001-task-struct.md +0 -29
  16. package/.savepoint/releases/v1/epics/E02-data-readers/tasks/T002-frontmatter-parser.md +0 -30
  17. package/.savepoint/releases/v1/epics/E02-data-readers/tasks/T003-router-reader.md +0 -29
  18. package/.savepoint/releases/v1/epics/E02-data-readers/tasks/T004-config-reader.md +0 -29
  19. package/.savepoint/releases/v1/epics/E02-data-readers/tasks/T005-discovery.md +0 -30
  20. package/.savepoint/releases/v1/epics/E03-board-tui-core/E03-Detail.md +0 -38
  21. package/.savepoint/releases/v1/epics/E03-board-tui-core/tasks/T001-model.md +0 -29
  22. package/.savepoint/releases/v1/epics/E03-board-tui-core/tasks/T002-update-loop.md +0 -30
  23. package/.savepoint/releases/v1/epics/E03-board-tui-core/tasks/T003-view.md +0 -34
  24. package/.savepoint/releases/v1/epics/E03-board-tui-core/tasks/T004-styles.md +0 -29
  25. package/.savepoint/releases/v1/epics/E03-board-tui-core/tasks/T005-layout.md +0 -42
  26. package/.savepoint/releases/v1/epics/E04-board-components/E04-Detail.md +0 -44
  27. package/.savepoint/releases/v1/epics/E04-board-components/tasks/T001-column.md +0 -34
  28. package/.savepoint/releases/v1/epics/E04-board-components/tasks/T002-card.md +0 -33
  29. package/.savepoint/releases/v1/epics/E04-board-components/tasks/T003-epic-panel.md +0 -49
  30. package/.savepoint/releases/v1/epics/E04-board-components/tasks/T004-detail-overlay.md +0 -40
  31. package/.savepoint/releases/v1/epics/E04-board-components/tasks/T005-release-dropdown.md +0 -33
  32. package/.savepoint/releases/v1/epics/E04-board-components/tasks/T006-help-overlay.md +0 -34
  33. package/.savepoint/releases/v1/epics/E05-phase-transitions/E05-Detail.md +0 -38
  34. package/.savepoint/releases/v1/epics/E05-phase-transitions/tasks/T001-phase-stepping.md +0 -29
  35. package/.savepoint/releases/v1/epics/E05-phase-transitions/tasks/T002-gates.md +0 -31
  36. package/.savepoint/releases/v1/epics/E05-phase-transitions/tasks/T003-write-task.md +0 -31
  37. package/.savepoint/releases/v1/epics/E05-phase-transitions/tasks/T004-write-router.md +0 -31
  38. package/.savepoint/releases/v1/epics/E06-atari-noir-layout/E06-Detail.md +0 -62
  39. package/.savepoint/releases/v1/epics/E06-atari-noir-layout/tasks/T001-color-system.md +0 -39
  40. package/.savepoint/releases/v1/epics/E06-atari-noir-layout/tasks/T002-header-and-dividers.md +0 -52
  41. package/.savepoint/releases/v1/epics/E06-atari-noir-layout/tasks/T003-footer-status-bar.md +0 -52
  42. package/.savepoint/releases/v1/epics/E06-atari-noir-layout/tasks/T004-component-refinement.md +0 -53
  43. package/.savepoint/releases/v1/epics/E06-atari-noir-layout/tasks/T005-restore-nav-hints.md +0 -39
  44. package/.savepoint/releases/v1/epics/E06-atari-noir-layout/tasks/T007-detail-card-fixes.md +0 -36
  45. package/.savepoint/releases/v1/epics/E06-atari-noir-layout/tasks/T008-checkbox-states.md +0 -40
  46. package/.savepoint/releases/v1/epics/E06-atari-noir-layout/tasks/T009-router-priority-marker.md +0 -48
  47. package/.savepoint/releases/v1/epics/E06-atari-noir-layout/tasks/T010-auto-refresh-watcher.md +0 -66
  48. package/.savepoint/releases/v1/epics/_archived/E01-archive-and-reset/Design.md +0 -39
  49. package/.savepoint/releases/v1/epics/_archived/E01-archive-and-reset/tasks/T001-archive-epics.md +0 -20
  50. package/.savepoint/releases/v1/epics/_archived/E01-archive-and-reset/tasks/T002-rewrite-prd.md +0 -22
  51. package/.savepoint/releases/v1/epics/_archived/E01-archive-and-reset/tasks/T003-create-epic-stubs.md +0 -24
  52. package/.savepoint/releases/v1/epics/_archived/E01-archive-and-reset/tasks/T004-update-router.md +0 -22
  53. package/.savepoint/releases/v1/epics/_archived/E01-scaffolding/Design.md +0 -118
  54. package/.savepoint/releases/v1/epics/_archived/E01-scaffolding/handoff.md +0 -9
  55. package/.savepoint/releases/v1/epics/_archived/E01-scaffolding/tasks/T001-package-baseline.md +0 -45
  56. package/.savepoint/releases/v1/epics/_archived/E01-scaffolding/tasks/T002-typescript-build.md +0 -48
  57. package/.savepoint/releases/v1/epics/_archived/E01-scaffolding/tasks/T003-vitest-smoke.md +0 -43
  58. package/.savepoint/releases/v1/epics/_archived/E01-scaffolding/tasks/T004-lint-format-gates.md +0 -45
  59. package/.savepoint/releases/v1/epics/_archived/E01-scaffolding/tasks/T005-scaffold-verification.md +0 -40
  60. package/.savepoint/releases/v1/epics/_archived/E02-data-model/Design.md +0 -142
  61. package/.savepoint/releases/v1/epics/_archived/E02-data-model/tasks/T001-domain-ids-status.md +0 -27
  62. package/.savepoint/releases/v1/epics/_archived/E02-data-model/tasks/T002-markdown-frontmatter-boundary.md +0 -28
  63. package/.savepoint/releases/v1/epics/_archived/E02-data-model/tasks/T003-task-documents.md +0 -29
  64. package/.savepoint/releases/v1/epics/_archived/E02-data-model/tasks/T004-release-epic-router-config-readers.md +0 -30
  65. package/.savepoint/releases/v1/epics/_archived/E02-data-model/tasks/T005-dependency-validation.md +0 -29
  66. package/.savepoint/releases/v1/epics/_archived/E02-data-model/tasks/T006-epic-task-set-reader.md +0 -29
  67. package/.savepoint/releases/v1/epics/_archived/E02-data-model/tasks/T007-quality-gates.md +0 -31
  68. package/.savepoint/releases/v1/epics/_archived/E02-domain-phase-model/Design.md +0 -40
  69. package/.savepoint/releases/v1/epics/_archived/E02-domain-phase-model/tasks/T001-phase-types.md +0 -27
  70. package/.savepoint/releases/v1/epics/_archived/E02-domain-phase-model/tasks/T002-phase-frontmatter.md +0 -25
  71. package/.savepoint/releases/v1/epics/_archived/E02-domain-phase-model/tasks/T003-simplify-config.md +0 -26
  72. package/.savepoint/releases/v1/epics/_archived/E02-domain-phase-model/tasks/T004-simplify-router-domain.md +0 -24
  73. package/.savepoint/releases/v1/epics/_archived/E03-cli-foundation/Design.md +0 -122
  74. package/.savepoint/releases/v1/epics/_archived/E03-cli-foundation/tasks/T001-argument-parser-contract.md +0 -28
  75. package/.savepoint/releases/v1/epics/_archived/E03-cli-foundation/tasks/T002-help-text-generation.md +0 -28
  76. package/.savepoint/releases/v1/epics/_archived/E03-cli-foundation/tasks/T003-terminal-environment-detection.md +0 -27
  77. package/.savepoint/releases/v1/epics/_archived/E03-cli-foundation/tasks/T004-command-stub-modules.md +0 -29
  78. package/.savepoint/releases/v1/epics/_archived/E03-cli-foundation/tasks/T005-cli-runner-dispatch.md +0 -34
  79. package/.savepoint/releases/v1/epics/_archived/E03-cli-foundation/tasks/T006-entrypoint-quality-gates.md +0 -32
  80. package/.savepoint/releases/v1/epics/_archived/E03-cli-simplify/Design.md +0 -43
  81. package/.savepoint/releases/v1/epics/_archived/E03-cli-simplify/tasks/T001-strip-args.md +0 -26
  82. package/.savepoint/releases/v1/epics/_archived/E03-cli-simplify/tasks/T002-strip-help.md +0 -23
  83. package/.savepoint/releases/v1/epics/_archived/E03-cli-simplify/tasks/T003-strip-run.md +0 -23
  84. package/.savepoint/releases/v1/epics/_archived/E03-cli-simplify/tasks/T004-delete-commands.md +0 -24
  85. package/.savepoint/releases/v1/epics/_archived/E03-cli-simplify/tasks/T005-update-cli-tests.md +0 -22
  86. package/.savepoint/releases/v1/epics/_archived/E04-board-phase-integration/Design.md +0 -48
  87. package/.savepoint/releases/v1/epics/_archived/E04-board-phase-integration/tasks/T001-board-data-phases.md +0 -26
  88. package/.savepoint/releases/v1/epics/_archived/E04-board-phase-integration/tasks/T002-phase-rendering.md +0 -28
  89. package/.savepoint/releases/v1/epics/_archived/E04-board-phase-integration/tasks/T003-detail-pane-phases.md +0 -27
  90. package/.savepoint/releases/v1/epics/_archived/E04-board-phase-integration/tasks/T004-phase-transitions.md +0 -42
  91. package/.savepoint/releases/v1/epics/_archived/E04-board-phase-integration/tasks/T005-phase-gates.md +0 -24
  92. package/.savepoint/releases/v1/epics/_archived/E04-board-phase-integration/tasks/T006-phase-write-back.md +0 -24
  93. package/.savepoint/releases/v1/epics/_archived/E04-board-phase-integration/tasks/T007-remove-audit-flow.md +0 -27
  94. package/.savepoint/releases/v1/epics/_archived/E04-board-phase-integration/tasks/T008-board-tests.md +0 -25
  95. package/.savepoint/releases/v1/epics/_archived/E04-templates-and-prompts/Design.md +0 -85
  96. package/.savepoint/releases/v1/epics/_archived/E04-templates-and-prompts/tasks/T001-project-template-assets.md +0 -17
  97. package/.savepoint/releases/v1/epics/_archived/E04-templates-and-prompts/tasks/T002-release-and-prompt-assets.md +0 -20
  98. package/.savepoint/releases/v1/epics/_archived/E04-templates-and-prompts/tasks/T003-template-registry-renderer.md +0 -22
  99. package/.savepoint/releases/v1/epics/_archived/E04-templates-and-prompts/tasks/T004-template-integrity-tests.md +0 -17
  100. package/.savepoint/releases/v1/epics/_archived/E04-templates-and-prompts/tasks/T005-template-closeout-quality-gates.md +0 -16
  101. package/.savepoint/releases/v1/epics/_archived/E05-init-command/Design.md +0 -88
  102. package/.savepoint/releases/v1/epics/_archived/E05-init-command/tasks/T001-init-cli-contract.md +0 -22
  103. package/.savepoint/releases/v1/epics/_archived/E05-init-command/tasks/T002-target-validation.md +0 -23
  104. package/.savepoint/releases/v1/epics/_archived/E05-init-command/tasks/T003-scaffold-writer.md +0 -24
  105. package/.savepoint/releases/v1/epics/_archived/E05-init-command/tasks/T004-magic-prompt-and-clipboard.md +0 -23
  106. package/.savepoint/releases/v1/epics/_archived/E05-init-command/tasks/T005-dev-deps-install-option.md +0 -24
  107. package/.savepoint/releases/v1/epics/_archived/E05-init-command/tasks/T006-init-command-integration.md +0 -28
  108. package/.savepoint/releases/v1/epics/_archived/E05-project-cleanup/Design.md +0 -53
  109. package/.savepoint/releases/v1/epics/_archived/E05-project-cleanup/tasks/T001-delete-dead-src.md +0 -23
  110. package/.savepoint/releases/v1/epics/_archived/E05-project-cleanup/tasks/T002-delete-dead-tests.md +0 -26
  111. package/.savepoint/releases/v1/epics/_archived/E05-project-cleanup/tasks/T003-delete-assets.md +0 -25
  112. package/.savepoint/releases/v1/epics/_archived/E05-project-cleanup/tasks/T004-clean-savepoint.md +0 -28
  113. package/.savepoint/releases/v1/epics/_archived/E05-project-cleanup/tasks/T005-rewrite-agents-md.md +0 -28
  114. package/.savepoint/releases/v1/epics/_archived/E05-project-cleanup/tasks/T006-clean-package-json.md +0 -23
  115. package/.savepoint/releases/v1/epics/_archived/E05-project-cleanup/tasks/T007-verify.md +0 -25
  116. package/.savepoint/releases/v1/epics/_archived/E06-tui-board/Design.md +0 -104
  117. package/.savepoint/releases/v1/epics/_archived/E06-tui-board/tasks/T001-board-command-data.md +0 -23
  118. package/.savepoint/releases/v1/epics/_archived/E06-tui-board/tasks/T002-board-view-state.md +0 -24
  119. package/.savepoint/releases/v1/epics/_archived/E06-tui-board/tasks/T003-transition-gates-and-writes.md +0 -25
  120. package/.savepoint/releases/v1/epics/_archived/E06-tui-board/tasks/T004-terminal-theme.md +0 -23
  121. package/.savepoint/releases/v1/epics/_archived/E06-tui-board/tasks/T005-ink-board-ui.md +0 -26
  122. package/.savepoint/releases/v1/epics/_archived/E06-tui-board/tasks/T006-board-integration-audit-entry.md +0 -24
  123. package/.savepoint/releases/v1/epics/_archived/E07-audit-pipeline/Design.md +0 -88
  124. package/.savepoint/releases/v1/epics/_archived/E07-audit-pipeline/tasks/T001-audit-cli-contract.md +0 -23
  125. package/.savepoint/releases/v1/epics/_archived/E07-audit-pipeline/tasks/T002-quality-gate-runner.md +0 -23
  126. package/.savepoint/releases/v1/epics/_archived/E07-audit-pipeline/tasks/T003-snapshot-and-prompt.md +0 -23
  127. package/.savepoint/releases/v1/epics/_archived/E07-audit-pipeline/tasks/T004-audit-orchestration-router.md +0 -27
  128. package/.savepoint/releases/v1/epics/_archived/E07-audit-pipeline/tasks/T005-proposal-validation-apply.md +0 -25
  129. package/.savepoint/releases/v1/epics/_archived/E07-audit-pipeline/tasks/T006-audit-review-state.md +0 -24
  130. package/.savepoint/releases/v1/epics/_archived/E07-audit-pipeline/tasks/T007-audit-review-ui.md +0 -26
  131. package/.savepoint/releases/v1/epics/_archived/E07-audit-pipeline/tasks/T008-audit-pipeline-integration.md +0 -24
  132. package/.savepoint/releases/v1/epics/_archived/E08-board-workflow-cleanup/Design.md +0 -103
  133. package/.savepoint/releases/v1/epics/_archived/E08-board-workflow-cleanup/tasks/T001-acceptance-criteria-model.md +0 -30
  134. package/.savepoint/releases/v1/epics/_archived/E08-board-workflow-cleanup/tasks/T002-release-task-set-reader.md +0 -33
  135. package/.savepoint/releases/v1/epics/_archived/E08-board-workflow-cleanup/tasks/T003-board-data-and-plain-output.md +0 -34
  136. package/.savepoint/releases/v1/epics/_archived/E08-board-workflow-cleanup/tasks/T004-board-selection-state.md +0 -33
  137. package/.savepoint/releases/v1/epics/_archived/E08-board-workflow-cleanup/tasks/T005-ink-board-layout-cleanup.md +0 -37
  138. package/.savepoint/releases/v1/epics/_archived/E08-board-workflow-cleanup/tasks/T006-task-detail-popup.md +0 -36
  139. package/.savepoint/releases/v1/epics/_archived/E08-board-workflow-cleanup/tasks/T007-templates-acceptance-criteria.md +0 -34
  140. package/.savepoint/releases/v1/epics/_archived/E08-board-workflow-cleanup/tasks/T008-board-workflow-integration.md +0 -41
  141. package/.savepoint/releases/v1/epics/_archived/E09-doctor-command/Design.md +0 -70
  142. package/.savepoint/releases/v1/epics/_archived/E10-docs-and-packaging/Design.md +0 -68
  143. package/.savepoint/releases/v1/epics/_archived/E11-release-validation/Design.md +0 -68
  144. package/.savepoint/releases/v1/v1-PRD.md +0 -66
  145. package/.savepoint/releases/v1.1/epics/E01-tui-optimisation/E01-Detail.md +0 -40
  146. package/.savepoint/releases/v1.1/epics/E01-tui-optimisation/tasks/T001-next-activity-header.md +0 -56
  147. package/.savepoint/releases/v1.1/epics/E01-tui-optimisation/tasks/T002-rename-epic-design-files.md +0 -38
  148. package/.savepoint/releases/v1.1/epics/E01-tui-optimisation/tasks/T003-rename-release-prd.md +0 -28
  149. package/.savepoint/releases/v1.1/epics/E01-tui-optimisation/tasks/T004-update-instruction-files.md +0 -51
  150. package/.savepoint/releases/v1.1/epics/E01-tui-optimisation/tasks/T005-update-cross-references.md +0 -45
  151. package/.savepoint/releases/v1.1/epics/E01-tui-optimisation/tasks/T006-column-and-detail-scrolling.md +0 -68
  152. package/.savepoint/releases/v1.1/epics/E01-tui-optimisation/tasks/T007-column-focus-border-stability.md +0 -57
  153. package/.savepoint/releases/v1.1/epics/E02-cross-platform-compatibility/E02-Audit.md +0 -124
  154. package/.savepoint/releases/v1.1/epics/E02-cross-platform-compatibility/E02-Detail.md +0 -49
  155. package/.savepoint/releases/v1.1/epics/E02-cross-platform-compatibility/tasks/T001-fix-makefile.md +0 -37
  156. package/.savepoint/releases/v1.1/epics/E02-cross-platform-compatibility/tasks/T002-linux-build-target.md +0 -38
  157. package/.savepoint/releases/v1.1/epics/E02-cross-platform-compatibility/tasks/T003-macos-build-target.md +0 -36
  158. package/.savepoint/releases/v1.1/epics/E02-cross-platform-compatibility/tasks/T004-smoke-tests-and-artifacts.md +0 -59
  159. package/.savepoint/releases/v1.1/epics/E03-ui-visual-refinement/E03-Audit.md +0 -195
  160. package/.savepoint/releases/v1.1/epics/E03-ui-visual-refinement/E03-Detail.md +0 -45
  161. package/.savepoint/releases/v1.1/epics/E03-ui-visual-refinement/tasks/T001-border-resize-fix.md +0 -40
  162. package/.savepoint/releases/v1.1/epics/E03-ui-visual-refinement/tasks/T002-next-activity-below-header.md +0 -64
  163. package/.savepoint/releases/v1.1/epics/E03-ui-visual-refinement/tasks/T003-checkbox-rendering-fix.md +0 -56
  164. package/.savepoint/releases/v1.1/epics/E03-ui-visual-refinement/tasks/T005-unify-status-glyphs.md +0 -65
  165. package/.savepoint/releases/v1.1/epics/E03-ui-visual-refinement/tasks/T006-forced-256-color-profile.md +0 -36
  166. package/.savepoint/releases/v1.1/epics/E04-epic-navigation/E04-Audit.md +0 -167
  167. package/.savepoint/releases/v1.1/epics/E04-epic-navigation/E04-Detail.md +0 -51
  168. package/.savepoint/releases/v1.1/epics/E04-epic-navigation/tasks/T001-sidebar-focusable-navigation.md +0 -65
  169. package/.savepoint/releases/v1.1/epics/E04-epic-navigation/tasks/T002-epic-detail-overlay.md +0 -73
  170. package/.savepoint/releases/v1.1/epics/E04-epic-navigation/tasks/T003-epic-status-glyphs.md +0 -73
  171. package/.savepoint/releases/v1.1/epics/E05-tasking-permissions/E05-Audit.md +0 -237
  172. package/.savepoint/releases/v1.1/epics/E05-tasking-permissions/E05-Detail.md +0 -54
  173. package/.savepoint/releases/v1.1/epics/E05-tasking-permissions/tasks/T001-update-agents-md.md +0 -45
  174. package/.savepoint/releases/v1.1/epics/E05-tasking-permissions/tasks/T002-update-router-md.md +0 -40
  175. package/.savepoint/releases/v1.1/epics/E05-tasking-permissions/tasks/T003-update-design-md.md +0 -47
  176. package/.savepoint/releases/v1.1/epics/E05-tasking-permissions/tasks/T004-implement-m-hotkey.md +0 -98
  177. package/.savepoint/releases/v1.1/epics/E05-tasking-permissions/tasks/T005-update-help-overlay.md +0 -33
  178. package/.savepoint/releases/v1.1/epics/E05-tasking-permissions/tasks/T006-tests-and-quality-gates.md +0 -62
  179. package/.savepoint/releases/v1.1/epics/E06-audit-command/E06-Audit.md +0 -56
  180. package/.savepoint/releases/v1.1/epics/E06-audit-command/E06-Detail.md +0 -63
  181. package/.savepoint/releases/v1.1/epics/E06-audit-command/tasks/T005-proposals.md +0 -44
  182. package/.savepoint/releases/v1.1/epics/E06-audit-command/tasks/T007-apply-close.md +0 -35
  183. package/.savepoint/releases/v1.1/epics/E06-audit-command/tasks/T009-integration.md +0 -40
  184. package/.savepoint/releases/v1.1/epics/E06-audit-command/tasks/T010-audit-file-migration.md +0 -45
  185. package/.savepoint/releases/v1.1/epics/E06-audit-command/tasks/T011-model-tab-state.md +0 -26
  186. package/.savepoint/releases/v1.1/epics/E06-audit-command/tasks/T012-epic-audit-render.md +0 -33
  187. package/.savepoint/releases/v1.1/epics/E06-audit-command/tasks/T013-handle-tab-keys.md +0 -34
  188. package/.savepoint/releases/v1.1/epics/E06-audit-command/tasks/T014-tab-indicator.md +0 -33
  189. package/.savepoint/releases/v1.1/epics/E07-init-command/E07-Audit.md +0 -336
  190. package/.savepoint/releases/v1.1/epics/E07-init-command/E07-Detail.md +0 -61
  191. package/.savepoint/releases/v1.1/epics/E07-init-command/tasks/T001-cli-entrypoint.md +0 -37
  192. package/.savepoint/releases/v1.1/epics/E07-init-command/tasks/T002-target-validation.md +0 -28
  193. package/.savepoint/releases/v1.1/epics/E07-init-command/tasks/T003-scaffold-writer.md +0 -46
  194. package/.savepoint/releases/v1.1/epics/E07-init-command/tasks/T004-atomic-writes.md +0 -27
  195. package/.savepoint/releases/v1.1/epics/E07-init-command/tasks/T005-magic-prompt.md +0 -25
  196. package/.savepoint/releases/v1.1/epics/E07-init-command/tasks/T006-clipboard.md +0 -26
  197. package/.savepoint/releases/v1.1/epics/E07-init-command/tasks/T007-integration-test.md +0 -26
  198. package/.savepoint/releases/v1.1/epics/E08-board-command/E08-Audit.md +0 -333
  199. package/.savepoint/releases/v1.1/epics/E08-board-command/E08-Detail.md +0 -68
  200. package/.savepoint/releases/v1.1/epics/E08-board-command/tasks/T001-cli-entrypoint.md +0 -26
  201. package/.savepoint/releases/v1.1/epics/E08-board-command/tasks/T002-non-tty-fallback.md +0 -27
  202. package/.savepoint/releases/v1.1/epics/E08-board-command/tasks/T003-tui-app-shell.md +0 -28
  203. package/.savepoint/releases/v1.1/epics/E08-board-command/tasks/T004-board-model.md +0 -29
  204. package/.savepoint/releases/v1.1/epics/E08-board-command/tasks/T005-detail-pane.md +0 -27
  205. package/.savepoint/releases/v1.1/epics/E08-board-command/tasks/T006-status-transitions.md +0 -29
  206. package/.savepoint/releases/v1.1/epics/E08-board-command/tasks/T007-theme-fallbacks.md +0 -29
  207. package/.savepoint/releases/v1.1/epics/E08-board-command/tasks/T008-integration-test.md +0 -27
  208. package/.savepoint/releases/v1.1/epics/E09-doctor-command/E09-Audit.md +0 -207
  209. package/.savepoint/releases/v1.1/epics/E09-doctor-command/E09-Detail.md +0 -65
  210. package/.savepoint/releases/v1.1/epics/E09-doctor-command/tasks/T001-cli-entrypoint.md +0 -24
  211. package/.savepoint/releases/v1.1/epics/E09-doctor-command/tasks/T002-config-router-validation.md +0 -28
  212. package/.savepoint/releases/v1.1/epics/E09-doctor-command/tasks/T003-structure-checks.md +0 -29
  213. package/.savepoint/releases/v1.1/epics/E09-doctor-command/tasks/T004-dependency-checks.md +0 -27
  214. package/.savepoint/releases/v1.1/epics/E09-doctor-command/tasks/T005-audit-orphan-checks.md +0 -28
  215. package/.savepoint/releases/v1.1/epics/E09-doctor-command/tasks/T006-quality-gates-report.md +0 -31
  216. package/.savepoint/releases/v1.1/epics/E11-board-refresh-fix/E11-Detail.md +0 -36
  217. package/.savepoint/releases/v1.1/epics/E11-board-refresh-fix/tasks/T001-debug-logging.md +0 -25
  218. package/.savepoint/releases/v1.1/epics/E11-board-refresh-fix/tasks/T002-increase-debounce.md +0 -21
  219. package/.savepoint/releases/v1.1/epics/E11-board-refresh-fix/tasks/T003-error-handling.md +0 -22
  220. package/.savepoint/releases/v1.1/epics/E11-board-refresh-fix/tasks/T004-test-verify.md +0 -29
  221. package/.savepoint/releases/v1.1/epics/E12-validation-fix/E12-Audit.md +0 -444
  222. package/.savepoint/releases/v1.1/epics/E12-validation-fix/E12-Detail.md +0 -45
  223. package/.savepoint/releases/v1.1/epics/E12-validation-fix/tasks/T001-default-phase.md +0 -35
  224. package/.savepoint/releases/v1.1/epics/E12-validation-fix/tasks/T002-default-status.md +0 -19
  225. package/.savepoint/releases/v1.1/epics/E12-validation-fix/tasks/T003-better-errors.md +0 -29
  226. package/.savepoint/releases/v1.1/epics/E12-validation-fix/tasks/T004-validate-on-write.md +0 -25
  227. package/.savepoint/releases/v1.1/epics/E12-validation-fix/tasks/T005-tests.md +0 -37
  228. package/.savepoint/releases/v1.1/epics/E13-audit-remediation/E13-Audit.md +0 -118
  229. package/.savepoint/releases/v1.1/epics/E13-audit-remediation/E13-Detail.md +0 -73
  230. package/.savepoint/releases/v1.1/epics/E13-audit-remediation/tasks/T001-safe-cleanup.md +0 -66
  231. package/.savepoint/releases/v1.1/epics/E13-audit-remediation/tasks/T002-bug-fixes.md +0 -35
  232. package/.savepoint/releases/v1.1/epics/E13-audit-remediation/tasks/T003-centralize-duplication.md +0 -60
  233. package/.savepoint/releases/v1.1/epics/E13-audit-remediation/tasks/T004-infrastructure.md +0 -33
  234. package/.savepoint/releases/v1.1/epics/E13-audit-remediation/tasks/T005-decompose-update.md +0 -37
  235. package/.savepoint/releases/v1.1/epics/E13-audit-remediation/tasks/T006-async-io.md +0 -40
  236. package/.savepoint/releases/v1.1/epics/E13-audit-remediation/tasks/T007-test-coverage.md +0 -37
  237. package/.savepoint/releases/v1.1/epics/E14-structural-improvements/E14-Audit.md +0 -267
  238. package/.savepoint/releases/v1.1/epics/E14-structural-improvements/E14-Detail.md +0 -54
  239. package/.savepoint/releases/v1.1/epics/E14-structural-improvements/tasks/T001-group-model.md +0 -39
  240. package/.savepoint/releases/v1.1/epics/E14-structural-improvements/tasks/T002-data-interfaces.md +0 -42
  241. package/.savepoint/releases/v1.1/epics/E14-structural-improvements/tasks/T003-discover-orphans.md +0 -33
  242. package/.savepoint/releases/v1.1/epics/E14-structural-improvements/tasks/T004-epic-panel-headings.md +0 -35
  243. package/.savepoint/releases/v1.1/epics/E14-structural-improvements/tasks/T005-shell-tokenization.md +0 -27
  244. package/.savepoint/releases/v1.1/epics/E14-structural-improvements/tasks/T006-unify-enums.md +0 -29
  245. package/.savepoint/releases/v1.1/epics/E14-structural-improvements/tasks/T007-testutil-package.md +0 -28
  246. package/.savepoint/releases/v1.1/epics/E15-hardening/E15-Detail.md +0 -43
  247. package/.savepoint/releases/v1.1/epics/E15-hardening/tasks/T001-benchmarks.md +0 -31
  248. package/.savepoint/releases/v1.1/epics/E15-hardening/tasks/T002-fuzz-targets.md +0 -28
  249. package/.savepoint/releases/v1.1/epics/E15-hardening/tasks/T003-debug-flag.md +0 -30
  250. package/.savepoint/releases/v1.1/epics/E15-hardening/tasks/T004-dist-checksums.md +0 -27
  251. package/.savepoint/releases/v1.1/epics/E15-hardening/tasks/T005-windows-targets.md +0 -28
  252. package/.savepoint/releases/v1.1/epics/E15-hardening/tasks/T006-abbreviation-splitting.md +0 -26
  253. package/.savepoint/releases/v1.1/epics/E15-hardening/tasks/T007-root-test-allowlist.md +0 -28
  254. package/.savepoint/releases/v1.1/epics/_archived/T001-cli-entrypoint.md +0 -25
  255. package/.savepoint/releases/v1.1/epics/_archived/T002-quality-gates.md +0 -27
  256. package/.savepoint/releases/v1.1/epics/_archived/T003-snapshot.md +0 -27
  257. package/.savepoint/releases/v1.1/epics/_archived/T004-ai-reconcile.md +0 -29
  258. package/.savepoint/releases/v1.1/epics/_archived/T006-tui-review.md +0 -31
  259. package/.savepoint/releases/v1.1/epics/_archived/T008-skip-handling.md +0 -34
  260. package/.savepoint/releases/v1.1/v1.1-PRD.md +0 -139
  261. package/.savepoint/router.md +0 -57
  262. package/.savepoint/visual-identity.md +0 -125
  263. package/AGENTS.md +0 -99
  264. package/CLAUDE.md +0 -1
  265. package/GEMINI.md +0 -1
  266. package/Makefile +0 -29
  267. package/agent-skills/ink-tui-design/SKILL.md +0 -309
  268. package/agent-skills/ink-tui-design/references/component-patterns.md +0 -371
  269. package/agent-skills/ink-tui-design/references/hooks-guide.md +0 -436
  270. package/agent-skills/ink-tui-design/references/ink-gotchas.md +0 -330
  271. package/agent-skills/ink-tui-design/references/testing-patterns.md +0 -384
  272. package/agent-skills/savepoint-audit/SKILL.md +0 -87
  273. package/agent-skills/savepoint-build-task/SKILL.md +0 -44
  274. package/agent-skills/savepoint-create-plan/SKILL.md +0 -33
  275. package/agent-skills/savepoint-create-task/SKILL.md +0 -44
  276. package/agent-skills/savepoint-draft-prd/SKILL.md +0 -37
  277. package/agent-skills/savepoint-system-design/SKILL.md +0 -38
  278. package/agent-skills/superpowers/brainstorming/SKILL.md +0 -165
  279. package/agent-skills/superpowers/brainstorming/visual-companion.md +0 -304
  280. package/agent-skills/superpowers/dispatching-parallel-agents/SKILL.md +0 -193
  281. package/agent-skills/superpowers/executing-plans/SKILL.md +0 -77
  282. package/agent-skills/superpowers/finishing-a-development-branch/SKILL.md +0 -213
  283. package/agent-skills/superpowers/receiving-code-review/SKILL.md +0 -226
  284. package/agent-skills/superpowers/requesting-code-review/SKILL.md +0 -115
  285. package/agent-skills/superpowers/requesting-code-review/code-reviewer.md +0 -160
  286. package/agent-skills/superpowers/subagent-driven-development/SKILL.md +0 -292
  287. package/agent-skills/superpowers/subagent-driven-development/code-quality-reviewer-prompt.md +0 -27
  288. package/agent-skills/superpowers/subagent-driven-development/implementer-prompt.md +0 -113
  289. package/agent-skills/superpowers/subagent-driven-development/spec-reviewer-prompt.md +0 -61
  290. package/agent-skills/superpowers/systematic-debugging/SKILL.md +0 -305
  291. package/agent-skills/superpowers/systematic-debugging/condition-based-waiting.md +0 -122
  292. package/agent-skills/superpowers/systematic-debugging/defense-in-depth.md +0 -130
  293. package/agent-skills/superpowers/systematic-debugging/root-cause-tracing.md +0 -183
  294. package/agent-skills/superpowers/test-driven-development/SKILL.md +0 -389
  295. package/agent-skills/superpowers/test-driven-development/testing-anti-patterns.md +0 -317
  296. package/agent-skills/superpowers/verification-before-completion/SKILL.md +0 -147
  297. package/agent-skills/superpowers/writing-plans/SKILL.md +0 -159
  298. package/agent-skills/superpowers/writing-plans/plan-document-reviewer-prompt.md +0 -49
  299. package/agent_skills_test.go +0 -91
  300. package/assets/banner.png +0 -0
  301. package/assets/logo.png +0 -0
  302. package/assets/strawman.png +0 -0
  303. package/cmd/board.go +0 -59
  304. package/cmd/board_test.go +0 -137
  305. package/cmd/doctor.go +0 -53
  306. package/cmd/doctor_test.go +0 -146
  307. package/cmd/init.go +0 -63
  308. package/cmd/init_test.go +0 -104
  309. package/go.mod +0 -36
  310. package/go.sum +0 -75
  311. package/internal/board/board.go +0 -177
  312. package/internal/board/board_test.go +0 -168
  313. package/internal/board/card.go +0 -129
  314. package/internal/board/card_test.go +0 -254
  315. package/internal/board/column.go +0 -127
  316. package/internal/board/column_test.go +0 -139
  317. package/internal/board/detail.go +0 -185
  318. package/internal/board/detail_test.go +0 -340
  319. package/internal/board/epic_panel.go +0 -262
  320. package/internal/board/epic_panel_test.go +0 -869
  321. package/internal/board/help.go +0 -41
  322. package/internal/board/help_test.go +0 -86
  323. package/internal/board/integration_test.go +0 -266
  324. package/internal/board/interfaces.go +0 -65
  325. package/internal/board/interfaces_test.go +0 -114
  326. package/internal/board/io.go +0 -93
  327. package/internal/board/layout.go +0 -68
  328. package/internal/board/layout_test.go +0 -106
  329. package/internal/board/model.go +0 -235
  330. package/internal/board/model_test.go +0 -67
  331. package/internal/board/plain.go +0 -88
  332. package/internal/board/plain_test.go +0 -117
  333. package/internal/board/release.go +0 -34
  334. package/internal/board/release_test.go +0 -177
  335. package/internal/board/render_policy_test.go +0 -77
  336. package/internal/board/status.go +0 -23
  337. package/internal/board/theme.go +0 -24
  338. package/internal/board/theme_test.go +0 -31
  339. package/internal/board/transitions.go +0 -113
  340. package/internal/board/transitions_test.go +0 -164
  341. package/internal/board/tui.go +0 -32
  342. package/internal/board/update.go +0 -556
  343. package/internal/board/update_test.go +0 -575
  344. package/internal/board/util.go +0 -76
  345. package/internal/board/view.go +0 -317
  346. package/internal/board/view_test.go +0 -315
  347. package/internal/board/watch.go +0 -130
  348. package/internal/buildtool/main.go +0 -211
  349. package/internal/buildtool/main_test.go +0 -46
  350. package/internal/data/config.go +0 -101
  351. package/internal/data/config_test.go +0 -122
  352. package/internal/data/discover.go +0 -178
  353. package/internal/data/discover_test.go +0 -130
  354. package/internal/data/errors.go +0 -13
  355. package/internal/data/lifecycle.go +0 -44
  356. package/internal/data/lifecycle_test.go +0 -41
  357. package/internal/data/parser.go +0 -242
  358. package/internal/data/parser_test.go +0 -281
  359. package/internal/data/router.go +0 -52
  360. package/internal/data/router_test.go +0 -35
  361. package/internal/data/task.go +0 -57
  362. package/internal/data/task_test.go +0 -51
  363. package/internal/data/write.go +0 -218
  364. package/internal/data/write_test.go +0 -623
  365. package/internal/doctor/checks.go +0 -567
  366. package/internal/doctor/checks_test.go +0 -716
  367. package/internal/doctor/gates.go +0 -193
  368. package/internal/doctor/gates_test.go +0 -166
  369. package/internal/doctor/interfaces.go +0 -64
  370. package/internal/doctor/interfaces_test.go +0 -104
  371. package/internal/doctor/repairs.go +0 -80
  372. package/internal/doctor/repairs_test.go +0 -81
  373. package/internal/doctor/report.go +0 -157
  374. package/internal/doctor/report_test.go +0 -89
  375. package/internal/init/clipboard.go +0 -146
  376. package/internal/init/clipboard_test.go +0 -74
  377. package/internal/init/install.go +0 -16
  378. package/internal/init/integration_test.go +0 -197
  379. package/internal/init/prompt.go +0 -14
  380. package/internal/init/prompt_test.go +0 -77
  381. package/internal/init/scaffold.go +0 -59
  382. package/internal/init/scaffold_test.go +0 -179
  383. package/internal/init/template_freshness_test.go +0 -56
  384. package/internal/init/validate.go +0 -85
  385. package/internal/init/validate_test.go +0 -141
  386. package/internal/init/write.go +0 -73
  387. package/internal/init/write_test.go +0 -91
  388. package/internal/styles/palette.go +0 -49
  389. package/internal/styles/styles.go +0 -139
  390. package/internal/styles/styles_test.go +0 -133
  391. package/internal/testutil/fixture.go +0 -113
  392. package/internal/testutil/fs.go +0 -26
  393. package/main.go +0 -117
  394. package/project-audit/audit_report_glm_5.1.md +0 -411
  395. package/project-audit/audit_report_opus_4.6 +0 -406
  396. package/project-audit/consolidated-audit-report.md +0 -456
  397. package/scripts/vitest-preload.cjs +0 -95
  398. package/templates/project/.savepoint/Design.md +0 -47
  399. package/templates/project/.savepoint/PRD.md +0 -34
  400. package/templates/project/.savepoint/config.yml +0 -27
  401. package/templates/project/.savepoint/router.md +0 -153
  402. package/templates/project/.savepoint/visual-identity.md +0 -122
  403. package/templates/project/AGENTS.md +0 -88
  404. package/templates/project/agent-skills/savepoint-audit/SKILL.md +0 -87
  405. package/templates/project/agent-skills/savepoint-build-task/SKILL.md +0 -44
  406. package/templates/project/agent-skills/savepoint-create-plan/SKILL.md +0 -33
  407. package/templates/project/agent-skills/savepoint-create-task/SKILL.md +0 -44
  408. package/templates/project/agent-skills/savepoint-draft-prd/SKILL.md +0 -37
  409. package/templates/project/agent-skills/savepoint-system-design/SKILL.md +0 -38
  410. package/templates/prompts/audit-reconciliation.prompt.md +0 -72
  411. package/templates/prompts/design.prompt.md +0 -45
  412. package/templates/prompts/epic-design.prompt.md +0 -43
  413. package/templates/prompts/magic-prompt.prompt.md +0 -7
  414. package/templates/prompts/prd.prompt.md +0 -42
  415. package/templates/prompts/task-breakdown.prompt.md +0 -54
  416. package/templates/prompts/task-building.prompt.md +0 -38
  417. package/templates/prompts/task-planning.prompt.md +0 -53
  418. package/templates/release/v1/PRD.md +0 -37
@@ -1,193 +0,0 @@
1
- package doctor
2
-
3
- import (
4
- "context"
5
- "fmt"
6
- "os"
7
- "os/exec"
8
- "path/filepath"
9
- "strings"
10
- "time"
11
- )
12
-
13
- // GateResult holds the outcome of a single quality gate.
14
- type GateResult struct {
15
- Name string
16
- Command string
17
- Passed bool
18
- ExitCode int
19
- Output string
20
- }
21
-
22
- // RunQualityGates executes configured quality gates (lint, typecheck, test).
23
- func RunQualityGates(root string, overrides ...DoctorDependencies) []GateResult {
24
- deps := doctorDependencies(overrides)
25
- configPath := filepath.Join(root, "config.yml")
26
- cfg, err := deps.ConfigReader.Read(configPath)
27
- if err != nil {
28
- return []GateResult{{
29
- Name: "config",
30
- Command: "",
31
- Passed: false,
32
- Output: fmt.Sprintf("cannot read config: %v", err),
33
- }}
34
- }
35
-
36
- timeout := 60 * time.Second
37
- if cfg.QualityGates.Timeout != "" {
38
- if d, err := time.ParseDuration(cfg.QualityGates.Timeout); err == nil {
39
- timeout = d
40
- }
41
- }
42
-
43
- var results []GateResult
44
-
45
- if cfg.QualityGates.Lint != nil && *cfg.QualityGates.Lint != "" {
46
- results = append(results, runGate("lint", *cfg.QualityGates.Lint, root, timeout))
47
- }
48
- if cfg.QualityGates.Typecheck != nil && *cfg.QualityGates.Typecheck != "" {
49
- results = append(results, runGate("typecheck", *cfg.QualityGates.Typecheck, root, timeout))
50
- }
51
- if cfg.QualityGates.Test != nil && *cfg.QualityGates.Test != "" {
52
- results = append(results, runGate("test", *cfg.QualityGates.Test, root, timeout))
53
- }
54
-
55
- if len(results) == 0 {
56
- results = append(results, GateResult{
57
- Name: "quality_gates",
58
- Command: "",
59
- Passed: true,
60
- Output: "no quality gates configured",
61
- })
62
- }
63
-
64
- return results
65
- }
66
-
67
- func runGate(name, command string, root string, timeout time.Duration) GateResult {
68
- parts := splitCommand(command)
69
- if len(parts) == 0 {
70
- return GateResult{
71
- Name: name,
72
- Command: command,
73
- Passed: false,
74
- Output: "empty command",
75
- }
76
- }
77
-
78
- ctx, cancel := context.WithTimeout(context.Background(), timeout)
79
- defer cancel()
80
-
81
- cmd := exec.CommandContext(ctx, parts[0], parts[1:]...)
82
- cmd.Dir = root
83
- cmd.Env = os.Environ()
84
-
85
- output, err := cmd.CombinedOutput()
86
- outStr := strings.TrimSpace(string(output))
87
-
88
- switch {
89
- case err != nil && ctx.Err() == context.DeadlineExceeded:
90
- return GateResult{
91
- Name: name,
92
- Command: command,
93
- Passed: false,
94
- Output: fmt.Sprintf("timed out after %v", timeout),
95
- }
96
- case err != nil:
97
- if exitErr, ok := err.(*exec.ExitError); ok {
98
- return GateResult{
99
- Name: name,
100
- Command: command,
101
- Passed: false,
102
- ExitCode: exitErr.ExitCode(),
103
- Output: outStr,
104
- }
105
- }
106
- return GateResult{
107
- Name: name,
108
- Command: command,
109
- Passed: false,
110
- Output: fmt.Sprintf("failed to execute: %v", err),
111
- }
112
- default:
113
- return GateResult{
114
- Name: name,
115
- Command: command,
116
- Passed: true,
117
- ExitCode: 0,
118
- Output: outStr,
119
- }
120
- }
121
- }
122
-
123
- func splitCommand(command string) []string {
124
- var parts []string
125
- current := strings.Builder{}
126
- inDoubleQuote := false
127
- inSingleQuote := false
128
- tokenStarted := false
129
-
130
- flush := func() {
131
- if tokenStarted || current.Len() > 0 {
132
- parts = append(parts, current.String())
133
- current.Reset()
134
- tokenStarted = false
135
- }
136
- }
137
-
138
- for i := 0; i < len(command); i++ {
139
- c := command[i]
140
-
141
- if inSingleQuote {
142
- tokenStarted = true
143
- if c == '\'' {
144
- inSingleQuote = false
145
- } else {
146
- current.WriteByte(c)
147
- }
148
- continue
149
- }
150
-
151
- if inDoubleQuote {
152
- tokenStarted = true
153
- if c == '\\' && i+1 < len(command) {
154
- next := command[i+1]
155
- if next == '"' || next == '\\' || next == '$' || next == '`' {
156
- i++
157
- current.WriteByte(command[i])
158
- continue
159
- }
160
- }
161
- if c == '"' {
162
- inDoubleQuote = false
163
- continue
164
- }
165
- current.WriteByte(c)
166
- continue
167
- }
168
-
169
- switch c {
170
- case '\\':
171
- tokenStarted = true
172
- if i+1 < len(command) {
173
- i++
174
- current.WriteByte(command[i])
175
- } else {
176
- current.WriteByte(c)
177
- }
178
- case '"':
179
- tokenStarted = true
180
- inDoubleQuote = true
181
- case '\'':
182
- tokenStarted = true
183
- inSingleQuote = true
184
- case ' ', '\t', '\n', '\r':
185
- flush()
186
- default:
187
- tokenStarted = true
188
- current.WriteByte(c)
189
- }
190
- }
191
- flush()
192
- return parts
193
- }
@@ -1,166 +0,0 @@
1
- package doctor
2
-
3
- import (
4
- "os"
5
- "path/filepath"
6
- "strings"
7
- "testing"
8
- )
9
-
10
- func writeConfig(t *testing.T, root, content string) {
11
- t.Helper()
12
- if err := os.WriteFile(filepath.Join(root, "config.yml"), []byte(content), 0644); err != nil {
13
- t.Fatal(err)
14
- }
15
- }
16
-
17
- func TestRunQualityGates_NoConfig(t *testing.T) {
18
- root := t.TempDir()
19
- results := RunQualityGates(root)
20
- if len(results) != 1 {
21
- t.Fatalf("RunQualityGates() = %d results, want 1", len(results))
22
- }
23
- if !results[0].Passed {
24
- t.Fatalf("RunQualityGates() = %v, want passed (default config has no gates)", results[0])
25
- }
26
- if !strings.Contains(results[0].Output, "no quality gates configured") {
27
- t.Fatalf("RunQualityGates() output = %q, want 'no quality gates configured'", results[0].Output)
28
- }
29
- }
30
-
31
- func TestRunQualityGates_AllNull(t *testing.T) {
32
- root := t.TempDir()
33
- writeConfig(t, root, "quality_gates:\n lint: null\n typecheck: null\n test: null\ntheme:\n bg: \"#000\"\n")
34
-
35
- results := RunQualityGates(root)
36
- if len(results) != 1 {
37
- t.Fatalf("RunQualityGates() = %d results, want 1 (no gates configured)", len(results))
38
- }
39
- if !results[0].Passed {
40
- t.Fatalf("RunQualityGates() = %v, want passed with 'no gates configured'", results[0])
41
- }
42
- if !strings.Contains(results[0].Output, "no quality gates configured") {
43
- t.Fatalf("RunQualityGates() output = %q, want 'no quality gates configured'", results[0].Output)
44
- }
45
- }
46
-
47
- func TestRunQualityGates_LintOnly(t *testing.T) {
48
- root := t.TempDir()
49
- writeConfig(t, root, "quality_gates:\n lint: \"go version\"\n typecheck: null\n test: null\ntheme:\n bg: \"#000\"\n")
50
-
51
- results := RunQualityGates(root)
52
- if len(results) != 1 {
53
- t.Fatalf("RunQualityGates() = %d results, want 1 (lint only)", len(results))
54
- }
55
- if !results[0].Passed {
56
- t.Fatalf("RunQualityGates() lint should pass: %v", results[0])
57
- }
58
- if results[0].Name != "lint" {
59
- t.Fatalf("RunQualityGates()[0].Name = %q, want \"lint\"", results[0].Name)
60
- }
61
- }
62
-
63
- func TestRunQualityGates_AllThree(t *testing.T) {
64
- root := t.TempDir()
65
- writeConfig(t, root, "quality_gates:\n lint: \"go version\"\n typecheck: \"go version\"\n test: \"go version\"\ntheme:\n bg: \"#000\"\n")
66
-
67
- results := RunQualityGates(root)
68
- if len(results) != 3 {
69
- t.Fatalf("RunQualityGates() = %d results, want 3", len(results))
70
- }
71
- for _, r := range results {
72
- if !r.Passed {
73
- t.Fatalf("RunQualityGates() %s should pass: %v", r.Name, r)
74
- }
75
- }
76
- }
77
-
78
- func TestRunQualityGates_FailingCommand(t *testing.T) {
79
- root := t.TempDir()
80
- writeConfig(t, root, "quality_gates:\n lint: \"cmd-that-does-not-exist-12345\"\n typecheck: null\n test: null\ntheme:\n bg: \"#000\"\n")
81
-
82
- results := RunQualityGates(root)
83
- if len(results) != 1 {
84
- t.Fatalf("RunQualityGates() = %d results, want 1", len(results))
85
- }
86
- if results[0].Passed {
87
- t.Fatal("RunQualityGates() should fail for non-existent command")
88
- }
89
- }
90
-
91
- func TestRunQualityGates_ExitCodeNonZero(t *testing.T) {
92
- root := t.TempDir()
93
- writeConfig(t, root, "quality_gates:\n lint: \"go vet\"\n typecheck: null\n test: null\ntheme:\n bg: \"#000\"\n")
94
- // Write a bad Go file so go vet fails
95
- badPath := filepath.Join(root, "bad.go")
96
- os.WriteFile(badPath, []byte("package x\n\nfunc f() { return 1 }\n"), 0644)
97
-
98
- results := RunQualityGates(root)
99
- if len(results) != 1 {
100
- t.Fatalf("RunQualityGates() = %d results, want 1", len(results))
101
- }
102
- if results[0].Passed {
103
- t.Fatal("RunQualityGates() should fail when go vet fails")
104
- }
105
- }
106
-
107
- func TestRunQualityGates_Timeout(t *testing.T) {
108
- root := t.TempDir()
109
- writeConfig(t, root, "quality_gates:\n lint: \"go test -test.run TestNonexistent -count=1 ./...\"\n gate_timeout: \"1ns\"\ntheme:\n bg: \"#000\"\n")
110
-
111
- results := RunQualityGates(root)
112
- if len(results) != 1 {
113
- t.Fatalf("RunQualityGates() = %d results, want 1", len(results))
114
- }
115
- if results[0].Passed {
116
- t.Fatal("RunQualityGates() should fail due to timeout")
117
- }
118
- if !strings.Contains(results[0].Output, "timed out") {
119
- t.Fatalf("RunQualityGates() output = %q, want 'timed out'", results[0].Output)
120
- }
121
- }
122
-
123
- func TestRunQualityGates_DefaultTimeout(t *testing.T) {
124
- root := t.TempDir()
125
- writeConfig(t, root, "quality_gates:\n lint: \"go version\"\n # no gate_timeout set — uses 60s default\ntheme:\n bg: \"#000\"\n")
126
-
127
- results := RunQualityGates(root)
128
- if len(results) != 1 {
129
- t.Fatalf("RunQualityGates() = %d results, want 1", len(results))
130
- }
131
- if !results[0].Passed {
132
- t.Fatalf("RunQualityGates() lint should pass with default timeout: %v", results[0])
133
- }
134
- }
135
-
136
- func TestSplitCommand(t *testing.T) {
137
- tests := []struct {
138
- input string
139
- want []string
140
- }{
141
- {"echo hello", []string{"echo", "hello"}},
142
- {"go test ./...", []string{"go", "test", "./..."}},
143
- {"\"c:\\program files\\go\\bin\\go\"", []string{"c:\\program files\\go\\bin\\go"}},
144
- {"echo 'hello world'", []string{"echo", "hello world"}},
145
- {"echo \"hello \\\"world\\\"\"", []string{"echo", "hello \"world\""}},
146
- {"echo hello\\ world", []string{"echo", "hello world"}},
147
- {"echo 'it''s'", []string{"echo", "its"}},
148
- {"go test -run \"\" ./...", []string{"go", "test", "-run", "", "./..."}},
149
- {"printf ''", []string{"printf", ""}},
150
- {"echo trailing\\", []string{"echo", "trailing\\"}},
151
- {"", nil},
152
- {" ", nil},
153
- }
154
- for _, tt := range tests {
155
- got := splitCommand(tt.input)
156
- if len(got) != len(tt.want) {
157
- t.Errorf("splitCommand(%q) = %v, want %v", tt.input, got, tt.want)
158
- continue
159
- }
160
- for i := range got {
161
- if got[i] != tt.want[i] {
162
- t.Errorf("splitCommand(%q)[%d] = %q, want %q", tt.input, i, got[i], tt.want[i])
163
- }
164
- }
165
- }
166
- }
@@ -1,64 +0,0 @@
1
- package doctor
2
-
3
- import "github.com/opencode/savepoint/internal/data"
4
-
5
- // taskDiscoverer provides project traversal for doctor checks.
6
- type taskDiscoverer interface {
7
- ListRootDirs(root string) ([]string, error)
8
- ListReleases(root string) ([]data.ReleaseInfo, error)
9
- ListEpics(root, release string) ([]data.EpicInfo, error)
10
- ListTasks(root, release, epic string) ([]data.TaskInfo, error)
11
- }
12
-
13
- // taskParser parses Savepoint frontmatter for doctor checks.
14
- type taskParser interface {
15
- ParseFrontmatter(content string) (map[string]any, error)
16
- }
17
-
18
- // configReader reads quality gate configuration.
19
- type configReader interface {
20
- Read(path string) (*data.Config, error)
21
- }
22
-
23
- // routerReader parses router state from router.md content.
24
- type routerReader interface {
25
- ReadState(content string) (*data.RouterState, error)
26
- }
27
-
28
- // DoctorDependencies contains doctor data-access dependencies.
29
- type DoctorDependencies struct {
30
- Discoverer taskDiscoverer
31
- Parser taskParser
32
- ConfigReader configReader
33
- RouterReader routerReader
34
- }
35
-
36
- func defaultDoctorDependencies() DoctorDependencies {
37
- return DoctorDependencies{
38
- Discoverer: data.NewDiscover(),
39
- Parser: data.NewParser(),
40
- ConfigReader: data.NewConfigReader(),
41
- RouterReader: data.NewRouterReader(),
42
- }
43
- }
44
-
45
- func doctorDependencies(overrides []DoctorDependencies) DoctorDependencies {
46
- deps := defaultDoctorDependencies()
47
- if len(overrides) == 0 {
48
- return deps
49
- }
50
- override := overrides[0]
51
- if override.Discoverer != nil {
52
- deps.Discoverer = override.Discoverer
53
- }
54
- if override.Parser != nil {
55
- deps.Parser = override.Parser
56
- }
57
- if override.ConfigReader != nil {
58
- deps.ConfigReader = override.ConfigReader
59
- }
60
- if override.RouterReader != nil {
61
- deps.RouterReader = override.RouterReader
62
- }
63
- return deps
64
- }
@@ -1,104 +0,0 @@
1
- package doctor
2
-
3
- import (
4
- "path/filepath"
5
- "testing"
6
-
7
- "github.com/opencode/savepoint/internal/data"
8
- "github.com/opencode/savepoint/internal/testutil"
9
- )
10
-
11
- type stubDoctorRouterReader struct {
12
- state *data.RouterState
13
- calls int
14
- }
15
-
16
- func (r *stubDoctorRouterReader) ReadState(content string) (*data.RouterState, error) {
17
- r.calls++
18
- return r.state, nil
19
- }
20
-
21
- type stubDoctorDiscoverer struct {
22
- releases []data.ReleaseInfo
23
- epics map[string][]data.EpicInfo
24
- tasks map[string][]data.TaskInfo
25
- calls int
26
- }
27
-
28
- func (d *stubDoctorDiscoverer) ListRootDirs(root string) ([]string, error) {
29
- d.calls++
30
- return nil, nil
31
- }
32
-
33
- func (d *stubDoctorDiscoverer) ListReleases(root string) ([]data.ReleaseInfo, error) {
34
- d.calls++
35
- return d.releases, nil
36
- }
37
-
38
- func (d *stubDoctorDiscoverer) ListEpics(root, release string) ([]data.EpicInfo, error) {
39
- d.calls++
40
- return d.epics[release], nil
41
- }
42
-
43
- func (d *stubDoctorDiscoverer) ListTasks(root, release, epic string) ([]data.TaskInfo, error) {
44
- d.calls++
45
- return d.tasks[release+"/"+epic], nil
46
- }
47
-
48
- type countingDoctorParser struct {
49
- parser *data.Parser
50
- calls int
51
- }
52
-
53
- func (p *countingDoctorParser) ParseFrontmatter(content string) (map[string]any, error) {
54
- p.calls++
55
- return p.parser.ParseFrontmatter(content)
56
- }
57
-
58
- func TestCheckRouterUsesInjectedRouterReader(t *testing.T) {
59
- root := t.TempDir()
60
- testutil.WriteFile(t, filepath.Join(root, "router.md"), "# intentionally not a router state block")
61
- testutil.MkdirAll(t, filepath.Join(root, "releases", "v9", "epics", "E01-mock"))
62
-
63
- reader := &stubDoctorRouterReader{state: &data.RouterState{
64
- State: "task-building",
65
- Release: "v9",
66
- Epic: "E01-mock",
67
- }}
68
-
69
- if err := CheckRouter(root, "", DoctorDependencies{RouterReader: reader}); err != nil {
70
- t.Fatalf("CheckRouter() with injected reader = %v, want nil", err)
71
- }
72
- if reader.calls != 1 {
73
- t.Fatalf("ReadState calls = %d, want 1", reader.calls)
74
- }
75
- }
76
-
77
- func TestCheckDependenciesUsesInjectedDiscovererAndParser(t *testing.T) {
78
- root := t.TempDir()
79
- taskPath := filepath.Join(root, "virtual", "T001-task.md")
80
- testutil.MkdirAll(t, filepath.Dir(taskPath))
81
- testutil.WriteFile(t, taskPath, "---\nid: E01-mock/T001-task\nstatus: planned\nobjective: Mock\ndepends_on: []\n---\n")
82
-
83
- discoverer := &stubDoctorDiscoverer{
84
- releases: []data.ReleaseInfo{{ID: "v9", Path: filepath.Join(root, "virtual-release")}},
85
- epics: map[string][]data.EpicInfo{
86
- "v9": {{ID: "E01-mock", Path: filepath.Join(root, "virtual-epic")}},
87
- },
88
- tasks: map[string][]data.TaskInfo{
89
- "v9/E01-mock": {{ID: "T001-task", Path: taskPath}},
90
- },
91
- }
92
- parser := &countingDoctorParser{parser: data.NewParser()}
93
-
94
- problems := CheckDependencies(root, "", DoctorDependencies{Discoverer: discoverer, Parser: parser})
95
- if len(problems) > 0 {
96
- t.Fatalf("CheckDependencies() = %v, want no problems", problems)
97
- }
98
- if discoverer.calls == 0 {
99
- t.Fatal("injected discoverer was not used")
100
- }
101
- if parser.calls != 1 {
102
- t.Fatalf("ParseFrontmatter calls = %d, want 1", parser.calls)
103
- }
104
- }
@@ -1,80 +0,0 @@
1
- package doctor
2
-
3
- import (
4
- "errors"
5
- "fmt"
6
- "strings"
7
-
8
- "github.com/opencode/savepoint/internal/data"
9
- )
10
-
11
- func SuggestRepair(err error) string {
12
- switch {
13
- case errors.Is(err, data.ErrConfigNotFound):
14
- return "Run `savepoint init` to scaffold a new project"
15
- case errors.Is(err, data.ErrInvalidStatus):
16
- return "Set router state to a recognized workflow state (see router.md State → action section)"
17
- case errors.Is(err, data.ErrMissingFrontmatter):
18
- return "Fix the YAML frontmatter between the --- delimiters"
19
- case errors.Is(err, data.ErrStructureProblem):
20
- return "Review the file and fix the reported issue"
21
- }
22
-
23
- msg := err.Error()
24
- switch {
25
- case strings.Contains(msg, "config.yml not found"):
26
- return "Run `savepoint init` to scaffold a new project"
27
- case strings.Contains(msg, "config.yml missing required field"):
28
- return "Add the missing field to config.yml — see the project template for reference"
29
- case strings.Contains(msg, "invalid YAML"):
30
- return "Fix the YAML syntax error at the indicated line"
31
- case strings.Contains(msg, "router.md not found"):
32
- return "Run `savepoint init` to scaffold a new project"
33
- case strings.Contains(msg, "unknown state"):
34
- return "Set router state to a recognized workflow state (see router.md State → action section)"
35
- case strings.Contains(msg, "release PRD file not found"):
36
- return "Create a {release}-PRD.md file with frontmatter for the release"
37
- case strings.Contains(msg, "release"):
38
- return "Create the release directory at releases/<release-id>/"
39
- case strings.Contains(msg, "epic") && strings.Contains(msg, "directory not found"):
40
- return "Create the epic directory at releases/<release>/epics/<epic-id>/"
41
- case strings.Contains(msg, "epic detail file not found"):
42
- return "Create an E##-Detail.md with frontmatter for the epic"
43
- case strings.Contains(msg, "invalid frontmatter"):
44
- return "Fix the YAML frontmatter between the --- delimiters"
45
- case strings.Contains(msg, "task missing required frontmatter field"):
46
- return "Add the missing field to the task frontmatter"
47
- case strings.Contains(msg, "missing ## Acceptance Criteria"):
48
- return "Add an ## Acceptance Criteria section with checkable items"
49
- case strings.Contains(msg, "depends_on must be a list"):
50
- return "Change depends_on to a YAML list format"
51
- case strings.Contains(msg, "references non-existent"):
52
- return "Create the referenced task or remove the dependency"
53
- case strings.Contains(msg, "duplicate task ID"):
54
- return "Rename one of the tasks to have a unique ID"
55
- case strings.Contains(msg, "dependency cycle"):
56
- return "Break the circular dependency chain between tasks"
57
- case strings.Contains(msg, "audit proposal exists"):
58
- return "Set router state to audit-pending for the matching epic, or remove stale audit files"
59
- case strings.Contains(msg, "orphaned"):
60
- return "Move the task directory to the correct epic or create the referenced epic"
61
- case strings.Contains(msg, "quality gate"):
62
- return "Fix the issue reported by the quality gate tool"
63
- default:
64
- return "Review the file and fix the reported issue"
65
- }
66
- }
67
-
68
- // GateSuggestion returns a command-specific repair hint.
69
- func GateSuggestion(name string) string {
70
- switch name {
71
- case "lint":
72
- return "Run `make lint` locally and fix reported issues"
73
- case "typecheck":
74
- return "Run `make typecheck` locally and fix type errors"
75
- case "test":
76
- return "Run `make test` locally and fix failing tests"
77
- default:
78
- return fmt.Sprintf("Run %q locally and fix reported issues", name)
79
- }
80
- }
@@ -1,81 +0,0 @@
1
- package doctor
2
-
3
- import (
4
- "errors"
5
- "fmt"
6
- "strings"
7
- "testing"
8
-
9
- "github.com/opencode/savepoint/internal/data"
10
- )
11
-
12
- func TestSuggestRepair(t *testing.T) {
13
- tests := []struct {
14
- err error
15
- contains string
16
- }{
17
- {Problem{Message: "config.yml not found"}, "savepoint init"},
18
- {Problem{Message: "config.yml missing required field: theme"}, "Add the missing field"},
19
- {Problem{Message: "config.yml invalid YAML: yaml: line 3: could not find expected"}, "Fix the YAML syntax"},
20
- {Problem{Message: "router.md not found"}, "savepoint init"},
21
- {Problem{Message: "router.md unknown state \"bogus\""}, "Set router state to a recognized"},
22
- {Problem{Message: "router.md release \"v99\" directory not found"}, "Create the release directory"},
23
- {Problem{Message: "router.md epic \"E99-foo\" directory not found"}, "Create the epic directory"},
24
- {Problem{Message: "release PRD file not found"}, "Create a {release}-PRD.md"},
25
- {Problem{Message: "epic detail file not found"}, "Create an E##-Detail.md"},
26
- {Problem{Message: "invalid frontmatter: yaml: line 5:"}, "Fix the YAML frontmatter"},
27
- {Problem{Message: "task missing required frontmatter field: status"}, "Add the missing field"},
28
- {Problem{Message: "task missing ## Acceptance Criteria section"}, "Add an ## Acceptance Criteria section"},
29
- {Problem{Message: "task frontmatter field depends_on must be a list"}, "Change depends_on to a YAML list"},
30
- {Problem{Message: "depends_on references non-existent task \"E99/T999\""}, "Create the referenced task"},
31
- {Problem{Message: "duplicate task ID \"E01-foo/T001-task\" (first seen in"}, "Rename one of the tasks"},
32
- {Problem{Message: "dependency cycle detected:"}, "Break the circular dependency chain"},
33
- {Problem{Message: "audit proposal exists but router state is"}, "Set router state to audit-pending"},
34
- {Problem{Message: "orphaned task: epic \"E99-ghost\" does not exist"}, "Move the task directory"},
35
- {Problem{Message: "quality gate \"lint\" failed"}, "Fix the issue reported by the quality gate"},
36
- {Problem{Message: "some random unknown problem"}, "Review the file and fix"},
37
- }
38
- for _, tt := range tests {
39
- got := SuggestRepair(tt.err)
40
- if !strings.Contains(got, tt.contains) {
41
- t.Errorf("SuggestRepair(%q) = %q, want containing %q", tt.err.Error(), got, tt.contains)
42
- }
43
- }
44
- }
45
-
46
- func TestGateSuggestion(t *testing.T) {
47
- tests := []struct {
48
- name string
49
- contains string
50
- }{
51
- {"lint", "make lint"},
52
- {"typecheck", "make typecheck"},
53
- {"test", "make test"},
54
- {"custom", "Run \"custom\" locally"},
55
- }
56
- for _, tt := range tests {
57
- got := GateSuggestion(tt.name)
58
- if !strings.Contains(got, tt.contains) {
59
- t.Errorf("GateSuggestion(%q) = %q, want containing %q", tt.name, got, tt.contains)
60
- }
61
- }
62
- }
63
-
64
- func TestSuggestRepair_typedErrors(t *testing.T) {
65
- tests := []struct {
66
- err error
67
- contains string
68
- }{
69
- {fmt.Errorf("config.yml not found: %w", data.ErrConfigNotFound), "savepoint init"},
70
- {fmt.Errorf("router.md not found: %w", data.ErrConfigNotFound), "savepoint init"},
71
- }
72
- for _, tt := range tests {
73
- if !errors.Is(tt.err, data.ErrConfigNotFound) {
74
- t.Fatalf("test error should wrap %v", data.ErrConfigNotFound)
75
- }
76
- got := SuggestRepair(tt.err)
77
- if !strings.Contains(got, tt.contains) {
78
- t.Errorf("SuggestRepair(%q) = %q, want containing %q", tt.err.Error(), got, tt.contains)
79
- }
80
- }
81
- }