savepoint 1.0.4 → 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 (425) hide show
  1. package/package.json +10 -3
  2. package/savepoint.exe +0 -0
  3. package/.claude/settings.local.json +0 -38
  4. package/.github/workflows/ci.yml +0 -20
  5. package/.golangci.yml +0 -11
  6. package/.prettierignore +0 -4
  7. package/.savepoint/Design.md +0 -207
  8. package/.savepoint/PRD.md +0 -58
  9. package/.savepoint/config.yml +0 -27
  10. package/.savepoint/releases/v1/epics/E01-go-setup/E01-Detail.md +0 -39
  11. package/.savepoint/releases/v1/epics/E01-go-setup/tasks/T001-init-module.md +0 -42
  12. package/.savepoint/releases/v1/epics/E01-go-setup/tasks/T002-entrypoint.md +0 -23
  13. package/.savepoint/releases/v1/epics/E01-go-setup/tasks/T003-directory-structure.md +0 -24
  14. package/.savepoint/releases/v1/epics/E01-go-setup/tasks/T004-makefile.md +0 -23
  15. package/.savepoint/releases/v1/epics/E02-data-readers/E02-Detail.md +0 -61
  16. package/.savepoint/releases/v1/epics/E02-data-readers/tasks/T001-task-struct.md +0 -29
  17. package/.savepoint/releases/v1/epics/E02-data-readers/tasks/T002-frontmatter-parser.md +0 -30
  18. package/.savepoint/releases/v1/epics/E02-data-readers/tasks/T003-router-reader.md +0 -29
  19. package/.savepoint/releases/v1/epics/E02-data-readers/tasks/T004-config-reader.md +0 -29
  20. package/.savepoint/releases/v1/epics/E02-data-readers/tasks/T005-discovery.md +0 -30
  21. package/.savepoint/releases/v1/epics/E03-board-tui-core/E03-Detail.md +0 -38
  22. package/.savepoint/releases/v1/epics/E03-board-tui-core/tasks/T001-model.md +0 -29
  23. package/.savepoint/releases/v1/epics/E03-board-tui-core/tasks/T002-update-loop.md +0 -30
  24. package/.savepoint/releases/v1/epics/E03-board-tui-core/tasks/T003-view.md +0 -34
  25. package/.savepoint/releases/v1/epics/E03-board-tui-core/tasks/T004-styles.md +0 -29
  26. package/.savepoint/releases/v1/epics/E03-board-tui-core/tasks/T005-layout.md +0 -42
  27. package/.savepoint/releases/v1/epics/E04-board-components/E04-Detail.md +0 -44
  28. package/.savepoint/releases/v1/epics/E04-board-components/tasks/T001-column.md +0 -34
  29. package/.savepoint/releases/v1/epics/E04-board-components/tasks/T002-card.md +0 -33
  30. package/.savepoint/releases/v1/epics/E04-board-components/tasks/T003-epic-panel.md +0 -49
  31. package/.savepoint/releases/v1/epics/E04-board-components/tasks/T004-detail-overlay.md +0 -40
  32. package/.savepoint/releases/v1/epics/E04-board-components/tasks/T005-release-dropdown.md +0 -33
  33. package/.savepoint/releases/v1/epics/E04-board-components/tasks/T006-help-overlay.md +0 -34
  34. package/.savepoint/releases/v1/epics/E05-phase-transitions/E05-Detail.md +0 -38
  35. package/.savepoint/releases/v1/epics/E05-phase-transitions/tasks/T001-phase-stepping.md +0 -29
  36. package/.savepoint/releases/v1/epics/E05-phase-transitions/tasks/T002-gates.md +0 -31
  37. package/.savepoint/releases/v1/epics/E05-phase-transitions/tasks/T003-write-task.md +0 -31
  38. package/.savepoint/releases/v1/epics/E05-phase-transitions/tasks/T004-write-router.md +0 -31
  39. package/.savepoint/releases/v1/epics/E06-atari-noir-layout/E06-Detail.md +0 -62
  40. package/.savepoint/releases/v1/epics/E06-atari-noir-layout/tasks/T001-color-system.md +0 -39
  41. package/.savepoint/releases/v1/epics/E06-atari-noir-layout/tasks/T002-header-and-dividers.md +0 -52
  42. package/.savepoint/releases/v1/epics/E06-atari-noir-layout/tasks/T003-footer-status-bar.md +0 -52
  43. package/.savepoint/releases/v1/epics/E06-atari-noir-layout/tasks/T004-component-refinement.md +0 -53
  44. package/.savepoint/releases/v1/epics/E06-atari-noir-layout/tasks/T005-restore-nav-hints.md +0 -39
  45. package/.savepoint/releases/v1/epics/E06-atari-noir-layout/tasks/T007-detail-card-fixes.md +0 -36
  46. package/.savepoint/releases/v1/epics/E06-atari-noir-layout/tasks/T008-checkbox-states.md +0 -40
  47. package/.savepoint/releases/v1/epics/E06-atari-noir-layout/tasks/T009-router-priority-marker.md +0 -48
  48. package/.savepoint/releases/v1/epics/E06-atari-noir-layout/tasks/T010-auto-refresh-watcher.md +0 -66
  49. package/.savepoint/releases/v1/epics/_archived/E01-archive-and-reset/Design.md +0 -39
  50. package/.savepoint/releases/v1/epics/_archived/E01-archive-and-reset/tasks/T001-archive-epics.md +0 -20
  51. package/.savepoint/releases/v1/epics/_archived/E01-archive-and-reset/tasks/T002-rewrite-prd.md +0 -22
  52. package/.savepoint/releases/v1/epics/_archived/E01-archive-and-reset/tasks/T003-create-epic-stubs.md +0 -24
  53. package/.savepoint/releases/v1/epics/_archived/E01-archive-and-reset/tasks/T004-update-router.md +0 -22
  54. package/.savepoint/releases/v1/epics/_archived/E01-scaffolding/Design.md +0 -118
  55. package/.savepoint/releases/v1/epics/_archived/E01-scaffolding/handoff.md +0 -9
  56. package/.savepoint/releases/v1/epics/_archived/E01-scaffolding/tasks/T001-package-baseline.md +0 -45
  57. package/.savepoint/releases/v1/epics/_archived/E01-scaffolding/tasks/T002-typescript-build.md +0 -48
  58. package/.savepoint/releases/v1/epics/_archived/E01-scaffolding/tasks/T003-vitest-smoke.md +0 -43
  59. package/.savepoint/releases/v1/epics/_archived/E01-scaffolding/tasks/T004-lint-format-gates.md +0 -45
  60. package/.savepoint/releases/v1/epics/_archived/E01-scaffolding/tasks/T005-scaffold-verification.md +0 -40
  61. package/.savepoint/releases/v1/epics/_archived/E02-data-model/Design.md +0 -142
  62. package/.savepoint/releases/v1/epics/_archived/E02-data-model/tasks/T001-domain-ids-status.md +0 -27
  63. package/.savepoint/releases/v1/epics/_archived/E02-data-model/tasks/T002-markdown-frontmatter-boundary.md +0 -28
  64. package/.savepoint/releases/v1/epics/_archived/E02-data-model/tasks/T003-task-documents.md +0 -29
  65. package/.savepoint/releases/v1/epics/_archived/E02-data-model/tasks/T004-release-epic-router-config-readers.md +0 -30
  66. package/.savepoint/releases/v1/epics/_archived/E02-data-model/tasks/T005-dependency-validation.md +0 -29
  67. package/.savepoint/releases/v1/epics/_archived/E02-data-model/tasks/T006-epic-task-set-reader.md +0 -29
  68. package/.savepoint/releases/v1/epics/_archived/E02-data-model/tasks/T007-quality-gates.md +0 -31
  69. package/.savepoint/releases/v1/epics/_archived/E02-domain-phase-model/Design.md +0 -40
  70. package/.savepoint/releases/v1/epics/_archived/E02-domain-phase-model/tasks/T001-phase-types.md +0 -27
  71. package/.savepoint/releases/v1/epics/_archived/E02-domain-phase-model/tasks/T002-phase-frontmatter.md +0 -25
  72. package/.savepoint/releases/v1/epics/_archived/E02-domain-phase-model/tasks/T003-simplify-config.md +0 -26
  73. package/.savepoint/releases/v1/epics/_archived/E02-domain-phase-model/tasks/T004-simplify-router-domain.md +0 -24
  74. package/.savepoint/releases/v1/epics/_archived/E03-cli-foundation/Design.md +0 -122
  75. package/.savepoint/releases/v1/epics/_archived/E03-cli-foundation/tasks/T001-argument-parser-contract.md +0 -28
  76. package/.savepoint/releases/v1/epics/_archived/E03-cli-foundation/tasks/T002-help-text-generation.md +0 -28
  77. package/.savepoint/releases/v1/epics/_archived/E03-cli-foundation/tasks/T003-terminal-environment-detection.md +0 -27
  78. package/.savepoint/releases/v1/epics/_archived/E03-cli-foundation/tasks/T004-command-stub-modules.md +0 -29
  79. package/.savepoint/releases/v1/epics/_archived/E03-cli-foundation/tasks/T005-cli-runner-dispatch.md +0 -34
  80. package/.savepoint/releases/v1/epics/_archived/E03-cli-foundation/tasks/T006-entrypoint-quality-gates.md +0 -32
  81. package/.savepoint/releases/v1/epics/_archived/E03-cli-simplify/Design.md +0 -43
  82. package/.savepoint/releases/v1/epics/_archived/E03-cli-simplify/tasks/T001-strip-args.md +0 -26
  83. package/.savepoint/releases/v1/epics/_archived/E03-cli-simplify/tasks/T002-strip-help.md +0 -23
  84. package/.savepoint/releases/v1/epics/_archived/E03-cli-simplify/tasks/T003-strip-run.md +0 -23
  85. package/.savepoint/releases/v1/epics/_archived/E03-cli-simplify/tasks/T004-delete-commands.md +0 -24
  86. package/.savepoint/releases/v1/epics/_archived/E03-cli-simplify/tasks/T005-update-cli-tests.md +0 -22
  87. package/.savepoint/releases/v1/epics/_archived/E04-board-phase-integration/Design.md +0 -48
  88. package/.savepoint/releases/v1/epics/_archived/E04-board-phase-integration/tasks/T001-board-data-phases.md +0 -26
  89. package/.savepoint/releases/v1/epics/_archived/E04-board-phase-integration/tasks/T002-phase-rendering.md +0 -28
  90. package/.savepoint/releases/v1/epics/_archived/E04-board-phase-integration/tasks/T003-detail-pane-phases.md +0 -27
  91. package/.savepoint/releases/v1/epics/_archived/E04-board-phase-integration/tasks/T004-phase-transitions.md +0 -42
  92. package/.savepoint/releases/v1/epics/_archived/E04-board-phase-integration/tasks/T005-phase-gates.md +0 -24
  93. package/.savepoint/releases/v1/epics/_archived/E04-board-phase-integration/tasks/T006-phase-write-back.md +0 -24
  94. package/.savepoint/releases/v1/epics/_archived/E04-board-phase-integration/tasks/T007-remove-audit-flow.md +0 -27
  95. package/.savepoint/releases/v1/epics/_archived/E04-board-phase-integration/tasks/T008-board-tests.md +0 -25
  96. package/.savepoint/releases/v1/epics/_archived/E04-templates-and-prompts/Design.md +0 -85
  97. package/.savepoint/releases/v1/epics/_archived/E04-templates-and-prompts/tasks/T001-project-template-assets.md +0 -17
  98. package/.savepoint/releases/v1/epics/_archived/E04-templates-and-prompts/tasks/T002-release-and-prompt-assets.md +0 -20
  99. package/.savepoint/releases/v1/epics/_archived/E04-templates-and-prompts/tasks/T003-template-registry-renderer.md +0 -22
  100. package/.savepoint/releases/v1/epics/_archived/E04-templates-and-prompts/tasks/T004-template-integrity-tests.md +0 -17
  101. package/.savepoint/releases/v1/epics/_archived/E04-templates-and-prompts/tasks/T005-template-closeout-quality-gates.md +0 -16
  102. package/.savepoint/releases/v1/epics/_archived/E05-init-command/Design.md +0 -88
  103. package/.savepoint/releases/v1/epics/_archived/E05-init-command/tasks/T001-init-cli-contract.md +0 -22
  104. package/.savepoint/releases/v1/epics/_archived/E05-init-command/tasks/T002-target-validation.md +0 -23
  105. package/.savepoint/releases/v1/epics/_archived/E05-init-command/tasks/T003-scaffold-writer.md +0 -24
  106. package/.savepoint/releases/v1/epics/_archived/E05-init-command/tasks/T004-magic-prompt-and-clipboard.md +0 -23
  107. package/.savepoint/releases/v1/epics/_archived/E05-init-command/tasks/T005-dev-deps-install-option.md +0 -24
  108. package/.savepoint/releases/v1/epics/_archived/E05-init-command/tasks/T006-init-command-integration.md +0 -28
  109. package/.savepoint/releases/v1/epics/_archived/E05-project-cleanup/Design.md +0 -53
  110. package/.savepoint/releases/v1/epics/_archived/E05-project-cleanup/tasks/T001-delete-dead-src.md +0 -23
  111. package/.savepoint/releases/v1/epics/_archived/E05-project-cleanup/tasks/T002-delete-dead-tests.md +0 -26
  112. package/.savepoint/releases/v1/epics/_archived/E05-project-cleanup/tasks/T003-delete-assets.md +0 -25
  113. package/.savepoint/releases/v1/epics/_archived/E05-project-cleanup/tasks/T004-clean-savepoint.md +0 -28
  114. package/.savepoint/releases/v1/epics/_archived/E05-project-cleanup/tasks/T005-rewrite-agents-md.md +0 -28
  115. package/.savepoint/releases/v1/epics/_archived/E05-project-cleanup/tasks/T006-clean-package-json.md +0 -23
  116. package/.savepoint/releases/v1/epics/_archived/E05-project-cleanup/tasks/T007-verify.md +0 -25
  117. package/.savepoint/releases/v1/epics/_archived/E06-tui-board/Design.md +0 -104
  118. package/.savepoint/releases/v1/epics/_archived/E06-tui-board/tasks/T001-board-command-data.md +0 -23
  119. package/.savepoint/releases/v1/epics/_archived/E06-tui-board/tasks/T002-board-view-state.md +0 -24
  120. package/.savepoint/releases/v1/epics/_archived/E06-tui-board/tasks/T003-transition-gates-and-writes.md +0 -25
  121. package/.savepoint/releases/v1/epics/_archived/E06-tui-board/tasks/T004-terminal-theme.md +0 -23
  122. package/.savepoint/releases/v1/epics/_archived/E06-tui-board/tasks/T005-ink-board-ui.md +0 -26
  123. package/.savepoint/releases/v1/epics/_archived/E06-tui-board/tasks/T006-board-integration-audit-entry.md +0 -24
  124. package/.savepoint/releases/v1/epics/_archived/E07-audit-pipeline/Design.md +0 -88
  125. package/.savepoint/releases/v1/epics/_archived/E07-audit-pipeline/tasks/T001-audit-cli-contract.md +0 -23
  126. package/.savepoint/releases/v1/epics/_archived/E07-audit-pipeline/tasks/T002-quality-gate-runner.md +0 -23
  127. package/.savepoint/releases/v1/epics/_archived/E07-audit-pipeline/tasks/T003-snapshot-and-prompt.md +0 -23
  128. package/.savepoint/releases/v1/epics/_archived/E07-audit-pipeline/tasks/T004-audit-orchestration-router.md +0 -27
  129. package/.savepoint/releases/v1/epics/_archived/E07-audit-pipeline/tasks/T005-proposal-validation-apply.md +0 -25
  130. package/.savepoint/releases/v1/epics/_archived/E07-audit-pipeline/tasks/T006-audit-review-state.md +0 -24
  131. package/.savepoint/releases/v1/epics/_archived/E07-audit-pipeline/tasks/T007-audit-review-ui.md +0 -26
  132. package/.savepoint/releases/v1/epics/_archived/E07-audit-pipeline/tasks/T008-audit-pipeline-integration.md +0 -24
  133. package/.savepoint/releases/v1/epics/_archived/E08-board-workflow-cleanup/Design.md +0 -103
  134. package/.savepoint/releases/v1/epics/_archived/E08-board-workflow-cleanup/tasks/T001-acceptance-criteria-model.md +0 -30
  135. package/.savepoint/releases/v1/epics/_archived/E08-board-workflow-cleanup/tasks/T002-release-task-set-reader.md +0 -33
  136. package/.savepoint/releases/v1/epics/_archived/E08-board-workflow-cleanup/tasks/T003-board-data-and-plain-output.md +0 -34
  137. package/.savepoint/releases/v1/epics/_archived/E08-board-workflow-cleanup/tasks/T004-board-selection-state.md +0 -33
  138. package/.savepoint/releases/v1/epics/_archived/E08-board-workflow-cleanup/tasks/T005-ink-board-layout-cleanup.md +0 -37
  139. package/.savepoint/releases/v1/epics/_archived/E08-board-workflow-cleanup/tasks/T006-task-detail-popup.md +0 -36
  140. package/.savepoint/releases/v1/epics/_archived/E08-board-workflow-cleanup/tasks/T007-templates-acceptance-criteria.md +0 -34
  141. package/.savepoint/releases/v1/epics/_archived/E08-board-workflow-cleanup/tasks/T008-board-workflow-integration.md +0 -41
  142. package/.savepoint/releases/v1/epics/_archived/E09-doctor-command/Design.md +0 -70
  143. package/.savepoint/releases/v1/epics/_archived/E10-docs-and-packaging/Design.md +0 -68
  144. package/.savepoint/releases/v1/epics/_archived/E11-release-validation/Design.md +0 -68
  145. package/.savepoint/releases/v1/v1-PRD.md +0 -66
  146. package/.savepoint/releases/v1.1/epics/E01-tui-optimisation/E01-Detail.md +0 -40
  147. package/.savepoint/releases/v1.1/epics/E01-tui-optimisation/tasks/T001-next-activity-header.md +0 -56
  148. package/.savepoint/releases/v1.1/epics/E01-tui-optimisation/tasks/T002-rename-epic-design-files.md +0 -38
  149. package/.savepoint/releases/v1.1/epics/E01-tui-optimisation/tasks/T003-rename-release-prd.md +0 -28
  150. package/.savepoint/releases/v1.1/epics/E01-tui-optimisation/tasks/T004-update-instruction-files.md +0 -51
  151. package/.savepoint/releases/v1.1/epics/E01-tui-optimisation/tasks/T005-update-cross-references.md +0 -45
  152. package/.savepoint/releases/v1.1/epics/E01-tui-optimisation/tasks/T006-column-and-detail-scrolling.md +0 -68
  153. package/.savepoint/releases/v1.1/epics/E01-tui-optimisation/tasks/T007-column-focus-border-stability.md +0 -57
  154. package/.savepoint/releases/v1.1/epics/E02-cross-platform-compatibility/E02-Audit.md +0 -124
  155. package/.savepoint/releases/v1.1/epics/E02-cross-platform-compatibility/E02-Detail.md +0 -49
  156. package/.savepoint/releases/v1.1/epics/E02-cross-platform-compatibility/tasks/T001-fix-makefile.md +0 -37
  157. package/.savepoint/releases/v1.1/epics/E02-cross-platform-compatibility/tasks/T002-linux-build-target.md +0 -38
  158. package/.savepoint/releases/v1.1/epics/E02-cross-platform-compatibility/tasks/T003-macos-build-target.md +0 -36
  159. package/.savepoint/releases/v1.1/epics/E02-cross-platform-compatibility/tasks/T004-smoke-tests-and-artifacts.md +0 -59
  160. package/.savepoint/releases/v1.1/epics/E03-ui-visual-refinement/E03-Audit.md +0 -195
  161. package/.savepoint/releases/v1.1/epics/E03-ui-visual-refinement/E03-Detail.md +0 -45
  162. package/.savepoint/releases/v1.1/epics/E03-ui-visual-refinement/tasks/T001-border-resize-fix.md +0 -40
  163. package/.savepoint/releases/v1.1/epics/E03-ui-visual-refinement/tasks/T002-next-activity-below-header.md +0 -64
  164. package/.savepoint/releases/v1.1/epics/E03-ui-visual-refinement/tasks/T003-checkbox-rendering-fix.md +0 -56
  165. package/.savepoint/releases/v1.1/epics/E03-ui-visual-refinement/tasks/T005-unify-status-glyphs.md +0 -65
  166. package/.savepoint/releases/v1.1/epics/E03-ui-visual-refinement/tasks/T006-forced-256-color-profile.md +0 -36
  167. package/.savepoint/releases/v1.1/epics/E04-epic-navigation/E04-Audit.md +0 -167
  168. package/.savepoint/releases/v1.1/epics/E04-epic-navigation/E04-Detail.md +0 -51
  169. package/.savepoint/releases/v1.1/epics/E04-epic-navigation/tasks/T001-sidebar-focusable-navigation.md +0 -65
  170. package/.savepoint/releases/v1.1/epics/E04-epic-navigation/tasks/T002-epic-detail-overlay.md +0 -73
  171. package/.savepoint/releases/v1.1/epics/E04-epic-navigation/tasks/T003-epic-status-glyphs.md +0 -73
  172. package/.savepoint/releases/v1.1/epics/E05-tasking-permissions/E05-Audit.md +0 -237
  173. package/.savepoint/releases/v1.1/epics/E05-tasking-permissions/E05-Detail.md +0 -54
  174. package/.savepoint/releases/v1.1/epics/E05-tasking-permissions/tasks/T001-update-agents-md.md +0 -45
  175. package/.savepoint/releases/v1.1/epics/E05-tasking-permissions/tasks/T002-update-router-md.md +0 -40
  176. package/.savepoint/releases/v1.1/epics/E05-tasking-permissions/tasks/T003-update-design-md.md +0 -47
  177. package/.savepoint/releases/v1.1/epics/E05-tasking-permissions/tasks/T004-implement-m-hotkey.md +0 -98
  178. package/.savepoint/releases/v1.1/epics/E05-tasking-permissions/tasks/T005-update-help-overlay.md +0 -33
  179. package/.savepoint/releases/v1.1/epics/E05-tasking-permissions/tasks/T006-tests-and-quality-gates.md +0 -62
  180. package/.savepoint/releases/v1.1/epics/E06-audit-command/E06-Audit.md +0 -56
  181. package/.savepoint/releases/v1.1/epics/E06-audit-command/E06-Detail.md +0 -63
  182. package/.savepoint/releases/v1.1/epics/E06-audit-command/tasks/T005-proposals.md +0 -44
  183. package/.savepoint/releases/v1.1/epics/E06-audit-command/tasks/T007-apply-close.md +0 -35
  184. package/.savepoint/releases/v1.1/epics/E06-audit-command/tasks/T009-integration.md +0 -40
  185. package/.savepoint/releases/v1.1/epics/E06-audit-command/tasks/T010-audit-file-migration.md +0 -45
  186. package/.savepoint/releases/v1.1/epics/E06-audit-command/tasks/T011-model-tab-state.md +0 -26
  187. package/.savepoint/releases/v1.1/epics/E06-audit-command/tasks/T012-epic-audit-render.md +0 -33
  188. package/.savepoint/releases/v1.1/epics/E06-audit-command/tasks/T013-handle-tab-keys.md +0 -34
  189. package/.savepoint/releases/v1.1/epics/E06-audit-command/tasks/T014-tab-indicator.md +0 -33
  190. package/.savepoint/releases/v1.1/epics/E07-init-command/E07-Audit.md +0 -336
  191. package/.savepoint/releases/v1.1/epics/E07-init-command/E07-Detail.md +0 -61
  192. package/.savepoint/releases/v1.1/epics/E07-init-command/tasks/T001-cli-entrypoint.md +0 -37
  193. package/.savepoint/releases/v1.1/epics/E07-init-command/tasks/T002-target-validation.md +0 -28
  194. package/.savepoint/releases/v1.1/epics/E07-init-command/tasks/T003-scaffold-writer.md +0 -46
  195. package/.savepoint/releases/v1.1/epics/E07-init-command/tasks/T004-atomic-writes.md +0 -27
  196. package/.savepoint/releases/v1.1/epics/E07-init-command/tasks/T005-magic-prompt.md +0 -25
  197. package/.savepoint/releases/v1.1/epics/E07-init-command/tasks/T006-clipboard.md +0 -26
  198. package/.savepoint/releases/v1.1/epics/E07-init-command/tasks/T007-integration-test.md +0 -26
  199. package/.savepoint/releases/v1.1/epics/E08-board-command/E08-Audit.md +0 -333
  200. package/.savepoint/releases/v1.1/epics/E08-board-command/E08-Detail.md +0 -68
  201. package/.savepoint/releases/v1.1/epics/E08-board-command/tasks/T001-cli-entrypoint.md +0 -26
  202. package/.savepoint/releases/v1.1/epics/E08-board-command/tasks/T002-non-tty-fallback.md +0 -27
  203. package/.savepoint/releases/v1.1/epics/E08-board-command/tasks/T003-tui-app-shell.md +0 -28
  204. package/.savepoint/releases/v1.1/epics/E08-board-command/tasks/T004-board-model.md +0 -29
  205. package/.savepoint/releases/v1.1/epics/E08-board-command/tasks/T005-detail-pane.md +0 -27
  206. package/.savepoint/releases/v1.1/epics/E08-board-command/tasks/T006-status-transitions.md +0 -29
  207. package/.savepoint/releases/v1.1/epics/E08-board-command/tasks/T007-theme-fallbacks.md +0 -29
  208. package/.savepoint/releases/v1.1/epics/E08-board-command/tasks/T008-integration-test.md +0 -27
  209. package/.savepoint/releases/v1.1/epics/E09-doctor-command/E09-Audit.md +0 -207
  210. package/.savepoint/releases/v1.1/epics/E09-doctor-command/E09-Detail.md +0 -65
  211. package/.savepoint/releases/v1.1/epics/E09-doctor-command/tasks/T001-cli-entrypoint.md +0 -24
  212. package/.savepoint/releases/v1.1/epics/E09-doctor-command/tasks/T002-config-router-validation.md +0 -28
  213. package/.savepoint/releases/v1.1/epics/E09-doctor-command/tasks/T003-structure-checks.md +0 -29
  214. package/.savepoint/releases/v1.1/epics/E09-doctor-command/tasks/T004-dependency-checks.md +0 -27
  215. package/.savepoint/releases/v1.1/epics/E09-doctor-command/tasks/T005-audit-orphan-checks.md +0 -28
  216. package/.savepoint/releases/v1.1/epics/E09-doctor-command/tasks/T006-quality-gates-report.md +0 -31
  217. package/.savepoint/releases/v1.1/epics/E11-board-refresh-fix/E11-Detail.md +0 -36
  218. package/.savepoint/releases/v1.1/epics/E11-board-refresh-fix/tasks/T001-debug-logging.md +0 -25
  219. package/.savepoint/releases/v1.1/epics/E11-board-refresh-fix/tasks/T002-increase-debounce.md +0 -21
  220. package/.savepoint/releases/v1.1/epics/E11-board-refresh-fix/tasks/T003-error-handling.md +0 -22
  221. package/.savepoint/releases/v1.1/epics/E11-board-refresh-fix/tasks/T004-test-verify.md +0 -29
  222. package/.savepoint/releases/v1.1/epics/E12-validation-fix/E12-Audit.md +0 -444
  223. package/.savepoint/releases/v1.1/epics/E12-validation-fix/E12-Detail.md +0 -45
  224. package/.savepoint/releases/v1.1/epics/E12-validation-fix/tasks/T001-default-phase.md +0 -35
  225. package/.savepoint/releases/v1.1/epics/E12-validation-fix/tasks/T002-default-status.md +0 -19
  226. package/.savepoint/releases/v1.1/epics/E12-validation-fix/tasks/T003-better-errors.md +0 -29
  227. package/.savepoint/releases/v1.1/epics/E12-validation-fix/tasks/T004-validate-on-write.md +0 -25
  228. package/.savepoint/releases/v1.1/epics/E12-validation-fix/tasks/T005-tests.md +0 -37
  229. package/.savepoint/releases/v1.1/epics/E13-audit-remediation/E13-Audit.md +0 -118
  230. package/.savepoint/releases/v1.1/epics/E13-audit-remediation/E13-Detail.md +0 -73
  231. package/.savepoint/releases/v1.1/epics/E13-audit-remediation/tasks/T001-safe-cleanup.md +0 -66
  232. package/.savepoint/releases/v1.1/epics/E13-audit-remediation/tasks/T002-bug-fixes.md +0 -35
  233. package/.savepoint/releases/v1.1/epics/E13-audit-remediation/tasks/T003-centralize-duplication.md +0 -60
  234. package/.savepoint/releases/v1.1/epics/E13-audit-remediation/tasks/T004-infrastructure.md +0 -33
  235. package/.savepoint/releases/v1.1/epics/E13-audit-remediation/tasks/T005-decompose-update.md +0 -37
  236. package/.savepoint/releases/v1.1/epics/E13-audit-remediation/tasks/T006-async-io.md +0 -40
  237. package/.savepoint/releases/v1.1/epics/E13-audit-remediation/tasks/T007-test-coverage.md +0 -37
  238. package/.savepoint/releases/v1.1/epics/E14-structural-improvements/E14-Audit.md +0 -267
  239. package/.savepoint/releases/v1.1/epics/E14-structural-improvements/E14-Detail.md +0 -54
  240. package/.savepoint/releases/v1.1/epics/E14-structural-improvements/tasks/T001-group-model.md +0 -39
  241. package/.savepoint/releases/v1.1/epics/E14-structural-improvements/tasks/T002-data-interfaces.md +0 -42
  242. package/.savepoint/releases/v1.1/epics/E14-structural-improvements/tasks/T003-discover-orphans.md +0 -33
  243. package/.savepoint/releases/v1.1/epics/E14-structural-improvements/tasks/T004-epic-panel-headings.md +0 -35
  244. package/.savepoint/releases/v1.1/epics/E14-structural-improvements/tasks/T005-shell-tokenization.md +0 -27
  245. package/.savepoint/releases/v1.1/epics/E14-structural-improvements/tasks/T006-unify-enums.md +0 -29
  246. package/.savepoint/releases/v1.1/epics/E14-structural-improvements/tasks/T007-testutil-package.md +0 -28
  247. package/.savepoint/releases/v1.1/epics/E15-hardening/E15-Audit.md +0 -272
  248. package/.savepoint/releases/v1.1/epics/E15-hardening/E15-Detail.md +0 -60
  249. package/.savepoint/releases/v1.1/epics/E15-hardening/tasks/T001-benchmarks.md +0 -31
  250. package/.savepoint/releases/v1.1/epics/E15-hardening/tasks/T002-fuzz-targets.md +0 -34
  251. package/.savepoint/releases/v1.1/epics/E15-hardening/tasks/T003-debug-flag.md +0 -30
  252. package/.savepoint/releases/v1.1/epics/E15-hardening/tasks/T004-dist-checksums.md +0 -27
  253. package/.savepoint/releases/v1.1/epics/E15-hardening/tasks/T005-windows-targets.md +0 -28
  254. package/.savepoint/releases/v1.1/epics/E15-hardening/tasks/T006-abbreviation-splitting.md +0 -26
  255. package/.savepoint/releases/v1.1/epics/E15-hardening/tasks/T007-root-test-allowlist.md +0 -33
  256. package/.savepoint/releases/v1.1/epics/E15-hardening/tasks/T008-ci-and-release-automation.md +0 -46
  257. package/.savepoint/releases/v1.1/epics/_archived/T001-cli-entrypoint.md +0 -25
  258. package/.savepoint/releases/v1.1/epics/_archived/T002-quality-gates.md +0 -27
  259. package/.savepoint/releases/v1.1/epics/_archived/T003-snapshot.md +0 -27
  260. package/.savepoint/releases/v1.1/epics/_archived/T004-ai-reconcile.md +0 -29
  261. package/.savepoint/releases/v1.1/epics/_archived/T006-tui-review.md +0 -31
  262. package/.savepoint/releases/v1.1/epics/_archived/T008-skip-handling.md +0 -34
  263. package/.savepoint/releases/v1.1/v1.1-PRD.md +0 -139
  264. package/.savepoint/router.md +0 -57
  265. package/.savepoint/visual-identity.md +0 -125
  266. package/AGENTS.md +0 -99
  267. package/CLAUDE.md +0 -1
  268. package/GEMINI.md +0 -1
  269. package/Makefile +0 -31
  270. package/agent-skills/ink-tui-design/SKILL.md +0 -309
  271. package/agent-skills/ink-tui-design/references/component-patterns.md +0 -371
  272. package/agent-skills/ink-tui-design/references/hooks-guide.md +0 -436
  273. package/agent-skills/ink-tui-design/references/ink-gotchas.md +0 -330
  274. package/agent-skills/ink-tui-design/references/testing-patterns.md +0 -384
  275. package/agent-skills/savepoint-audit/SKILL.md +0 -87
  276. package/agent-skills/savepoint-build-task/SKILL.md +0 -44
  277. package/agent-skills/savepoint-create-plan/SKILL.md +0 -33
  278. package/agent-skills/savepoint-create-task/SKILL.md +0 -44
  279. package/agent-skills/savepoint-draft-prd/SKILL.md +0 -37
  280. package/agent-skills/savepoint-system-design/SKILL.md +0 -38
  281. package/agent-skills/superpowers/brainstorming/SKILL.md +0 -165
  282. package/agent-skills/superpowers/brainstorming/visual-companion.md +0 -304
  283. package/agent-skills/superpowers/dispatching-parallel-agents/SKILL.md +0 -193
  284. package/agent-skills/superpowers/executing-plans/SKILL.md +0 -77
  285. package/agent-skills/superpowers/finishing-a-development-branch/SKILL.md +0 -213
  286. package/agent-skills/superpowers/receiving-code-review/SKILL.md +0 -226
  287. package/agent-skills/superpowers/requesting-code-review/SKILL.md +0 -115
  288. package/agent-skills/superpowers/requesting-code-review/code-reviewer.md +0 -160
  289. package/agent-skills/superpowers/subagent-driven-development/SKILL.md +0 -292
  290. package/agent-skills/superpowers/subagent-driven-development/code-quality-reviewer-prompt.md +0 -27
  291. package/agent-skills/superpowers/subagent-driven-development/implementer-prompt.md +0 -113
  292. package/agent-skills/superpowers/subagent-driven-development/spec-reviewer-prompt.md +0 -61
  293. package/agent-skills/superpowers/systematic-debugging/SKILL.md +0 -305
  294. package/agent-skills/superpowers/systematic-debugging/condition-based-waiting.md +0 -122
  295. package/agent-skills/superpowers/systematic-debugging/defense-in-depth.md +0 -130
  296. package/agent-skills/superpowers/systematic-debugging/root-cause-tracing.md +0 -183
  297. package/agent-skills/superpowers/test-driven-development/SKILL.md +0 -389
  298. package/agent-skills/superpowers/test-driven-development/testing-anti-patterns.md +0 -317
  299. package/agent-skills/superpowers/verification-before-completion/SKILL.md +0 -147
  300. package/agent-skills/superpowers/writing-plans/SKILL.md +0 -159
  301. package/agent-skills/superpowers/writing-plans/plan-document-reviewer-prompt.md +0 -49
  302. package/agent_skills_test.go +0 -91
  303. package/assets/banner.png +0 -0
  304. package/assets/logo.png +0 -0
  305. package/assets/strawman.png +0 -0
  306. package/cmd/board.go +0 -59
  307. package/cmd/board_test.go +0 -137
  308. package/cmd/doctor.go +0 -53
  309. package/cmd/doctor_test.go +0 -146
  310. package/cmd/init.go +0 -63
  311. package/cmd/init_test.go +0 -104
  312. package/go.mod +0 -36
  313. package/go.sum +0 -75
  314. package/internal/board/board.go +0 -181
  315. package/internal/board/board_test.go +0 -168
  316. package/internal/board/card.go +0 -129
  317. package/internal/board/card_test.go +0 -287
  318. package/internal/board/column.go +0 -156
  319. package/internal/board/column_test.go +0 -210
  320. package/internal/board/debug.go +0 -26
  321. package/internal/board/debug_test.go +0 -108
  322. package/internal/board/detail.go +0 -218
  323. package/internal/board/detail_test.go +0 -388
  324. package/internal/board/epic_panel.go +0 -264
  325. package/internal/board/epic_panel_test.go +0 -869
  326. package/internal/board/help.go +0 -41
  327. package/internal/board/help_test.go +0 -86
  328. package/internal/board/integration_test.go +0 -266
  329. package/internal/board/interfaces.go +0 -65
  330. package/internal/board/interfaces_test.go +0 -114
  331. package/internal/board/io.go +0 -93
  332. package/internal/board/layout.go +0 -68
  333. package/internal/board/layout_test.go +0 -106
  334. package/internal/board/model.go +0 -235
  335. package/internal/board/model_test.go +0 -67
  336. package/internal/board/plain.go +0 -88
  337. package/internal/board/plain_test.go +0 -117
  338. package/internal/board/release.go +0 -34
  339. package/internal/board/release_test.go +0 -177
  340. package/internal/board/render_policy_test.go +0 -77
  341. package/internal/board/status.go +0 -23
  342. package/internal/board/theme.go +0 -24
  343. package/internal/board/theme_test.go +0 -31
  344. package/internal/board/transitions.go +0 -113
  345. package/internal/board/transitions_test.go +0 -164
  346. package/internal/board/tui.go +0 -32
  347. package/internal/board/update.go +0 -575
  348. package/internal/board/update_test.go +0 -602
  349. package/internal/board/util.go +0 -76
  350. package/internal/board/view.go +0 -317
  351. package/internal/board/view_test.go +0 -377
  352. package/internal/board/watch.go +0 -136
  353. package/internal/buildtool/main.go +0 -249
  354. package/internal/buildtool/main_test.go +0 -224
  355. package/internal/data/config.go +0 -101
  356. package/internal/data/config_test.go +0 -122
  357. package/internal/data/discover.go +0 -178
  358. package/internal/data/discover_test.go +0 -130
  359. package/internal/data/errors.go +0 -13
  360. package/internal/data/fuzz_test.go +0 -75
  361. package/internal/data/lifecycle.go +0 -44
  362. package/internal/data/lifecycle_test.go +0 -41
  363. package/internal/data/parser.go +0 -243
  364. package/internal/data/parser_test.go +0 -281
  365. package/internal/data/router.go +0 -52
  366. package/internal/data/router_test.go +0 -35
  367. package/internal/data/task.go +0 -57
  368. package/internal/data/task_test.go +0 -51
  369. package/internal/data/testdata/fuzz/FuzzSplitFrontmatterBody/68eb66b0fe91e7e3 +0 -2
  370. package/internal/data/write.go +0 -221
  371. package/internal/data/write_test.go +0 -623
  372. package/internal/doctor/checks.go +0 -567
  373. package/internal/doctor/checks_test.go +0 -716
  374. package/internal/doctor/gates.go +0 -193
  375. package/internal/doctor/gates_test.go +0 -166
  376. package/internal/doctor/interfaces.go +0 -64
  377. package/internal/doctor/interfaces_test.go +0 -104
  378. package/internal/doctor/repairs.go +0 -80
  379. package/internal/doctor/repairs_test.go +0 -81
  380. package/internal/doctor/report.go +0 -157
  381. package/internal/doctor/report_test.go +0 -89
  382. package/internal/init/clipboard.go +0 -146
  383. package/internal/init/clipboard_test.go +0 -74
  384. package/internal/init/install.go +0 -16
  385. package/internal/init/integration_test.go +0 -197
  386. package/internal/init/prompt.go +0 -14
  387. package/internal/init/prompt_test.go +0 -77
  388. package/internal/init/scaffold.go +0 -59
  389. package/internal/init/scaffold_test.go +0 -179
  390. package/internal/init/template_freshness_test.go +0 -56
  391. package/internal/init/validate.go +0 -85
  392. package/internal/init/validate_test.go +0 -141
  393. package/internal/init/write.go +0 -73
  394. package/internal/init/write_test.go +0 -91
  395. package/internal/styles/palette.go +0 -49
  396. package/internal/styles/styles.go +0 -139
  397. package/internal/styles/styles_test.go +0 -133
  398. package/internal/testutil/fixture.go +0 -113
  399. package/internal/testutil/fs.go +0 -26
  400. package/main.go +0 -136
  401. package/project-audit/audit_report_glm_5.1.md +0 -411
  402. package/project-audit/audit_report_opus_4.6.md +0 -406
  403. package/project-audit/consolidated-audit-report.md +0 -456
  404. package/scripts/vitest-preload.cjs +0 -95
  405. package/templates/project/.savepoint/Design.md +0 -47
  406. package/templates/project/.savepoint/PRD.md +0 -34
  407. package/templates/project/.savepoint/config.yml +0 -27
  408. package/templates/project/.savepoint/router.md +0 -153
  409. package/templates/project/.savepoint/visual-identity.md +0 -122
  410. package/templates/project/AGENTS.md +0 -88
  411. package/templates/project/agent-skills/savepoint-audit/SKILL.md +0 -87
  412. package/templates/project/agent-skills/savepoint-build-task/SKILL.md +0 -44
  413. package/templates/project/agent-skills/savepoint-create-plan/SKILL.md +0 -33
  414. package/templates/project/agent-skills/savepoint-create-task/SKILL.md +0 -44
  415. package/templates/project/agent-skills/savepoint-draft-prd/SKILL.md +0 -37
  416. package/templates/project/agent-skills/savepoint-system-design/SKILL.md +0 -38
  417. package/templates/prompts/audit-reconciliation.prompt.md +0 -72
  418. package/templates/prompts/design.prompt.md +0 -45
  419. package/templates/prompts/epic-design.prompt.md +0 -43
  420. package/templates/prompts/magic-prompt.prompt.md +0 -7
  421. package/templates/prompts/prd.prompt.md +0 -42
  422. package/templates/prompts/task-breakdown.prompt.md +0 -54
  423. package/templates/prompts/task-building.prompt.md +0 -38
  424. package/templates/prompts/task-planning.prompt.md +0 -53
  425. package/templates/release/v1/PRD.md +0 -37
@@ -1,68 +0,0 @@
1
- package board
2
-
3
- const (
4
- colOverhead = 4 // rounded border (1) + padding (1) each side
5
-
6
- minColWidth = 10
7
- minContentHeight = 5
8
-
9
- epicPanelWidth = 28
10
- epicPanelOverhead = 4
11
-
12
- boardFrameOverhead = 4 // rounded border (2) + padding (2×1)
13
-
14
- breakpointWide = 120
15
- breakpointNarrow = 80
16
- )
17
-
18
- // Layout describes board geometry for a given terminal size.
19
- type Layout struct {
20
- EpicPanelVisible bool
21
- EpicPanelWidth int
22
- ColCount int
23
- ColWidths []int
24
- ContentHeight int
25
- }
26
-
27
- // CalculateLayout returns the board layout for the given terminal dimensions.
28
- //
29
- // - >=120 cols: epic panel (28w) + 3 columns
30
- // - 80–119 cols: 3 columns only
31
- // - <80 cols: 1 column
32
- func CalculateLayout(width, height int) Layout {
33
- return CalculateLayoutWithChrome(width, height, 0)
34
- }
35
-
36
- func CalculateLayoutWithChrome(width, height, extraHeaderLines int) Layout {
37
- contentHeight := max(height-10-extraHeaderLines, minContentHeight)
38
- inner := width - boardFrameOverhead
39
- switch {
40
- case width >= breakpointWide:
41
- available := inner - (epicPanelWidth + epicPanelOverhead) - 3*colOverhead
42
- cw := max(available/3, minColWidth)
43
- return Layout{
44
- EpicPanelVisible: true,
45
- EpicPanelWidth: epicPanelWidth,
46
- ColCount: 3,
47
- ColWidths: []int{cw, cw, cw},
48
- ContentHeight: contentHeight,
49
- }
50
- case width >= breakpointNarrow:
51
- available := inner - 3*colOverhead
52
- cw := max(available/3, minColWidth)
53
- return Layout{
54
- EpicPanelVisible: false,
55
- ColCount: 3,
56
- ColWidths: []int{cw, cw, cw},
57
- ContentHeight: contentHeight,
58
- }
59
- default:
60
- cw := max(inner-colOverhead, minColWidth)
61
- return Layout{
62
- EpicPanelVisible: false,
63
- ColCount: 1,
64
- ColWidths: []int{cw},
65
- ContentHeight: contentHeight,
66
- }
67
- }
68
- }
@@ -1,106 +0,0 @@
1
- package board
2
-
3
- import "testing"
4
-
5
- func TestCalculateLayout_wide(t *testing.T) {
6
- l := CalculateLayout(120, 40)
7
- if !l.EpicPanelVisible {
8
- t.Error("expected epic panel visible at width=120")
9
- }
10
- if l.EpicPanelWidth != epicPanelWidth {
11
- t.Errorf("EpicPanelWidth = %d, want %d", l.EpicPanelWidth, epicPanelWidth)
12
- }
13
- if l.ColCount != 3 {
14
- t.Errorf("ColCount = %d, want 3", l.ColCount)
15
- }
16
- if len(l.ColWidths) != 3 {
17
- t.Fatalf("len(ColWidths) = %d, want 3", len(l.ColWidths))
18
- }
19
- // inner = 120-4 = 116; available = 116-(28+4)-3*4 = 72; cw = 72/3 = 24
20
- for i, w := range l.ColWidths {
21
- if w != 24 {
22
- t.Errorf("ColWidths[%d] = %d, want 24", i, w)
23
- }
24
- }
25
- if l.ContentHeight != 30 {
26
- t.Errorf("ContentHeight = %d, want 30", l.ContentHeight)
27
- }
28
- }
29
-
30
- func TestCalculateLayout_medium(t *testing.T) {
31
- l := CalculateLayout(100, 40)
32
- if l.EpicPanelVisible {
33
- t.Error("epic panel should be hidden at width=100")
34
- }
35
- if l.ColCount != 3 {
36
- t.Errorf("ColCount = %d, want 3", l.ColCount)
37
- }
38
- if len(l.ColWidths) != 3 {
39
- t.Fatalf("len(ColWidths) = %d, want 3", len(l.ColWidths))
40
- }
41
- for i, w := range l.ColWidths {
42
- if w != 28 {
43
- t.Errorf("ColWidths[%d] = %d, want 28", i, w)
44
- }
45
- }
46
- }
47
-
48
- func TestCalculateLayout_narrow(t *testing.T) {
49
- l := CalculateLayout(60, 40)
50
- if l.EpicPanelVisible {
51
- t.Error("epic panel should be hidden at width=60")
52
- }
53
- if l.ColCount != 1 {
54
- t.Errorf("ColCount = %d, want 1", l.ColCount)
55
- }
56
- // inner = 60 - 4 = 56; cw = 56 - 4 = 52
57
- if l.ColWidths[0] != 52 {
58
- t.Errorf("ColWidths[0] = %d, want 52", l.ColWidths[0])
59
- }
60
- }
61
-
62
- func TestCalculateLayout_tinyWidth_floorsAtMinColWidth(t *testing.T) {
63
- l := CalculateLayout(4, 40)
64
- if l.ColCount != 1 {
65
- t.Errorf("ColCount = %d, want 1", l.ColCount)
66
- }
67
- if l.ColWidths[0] != minColWidth {
68
- t.Errorf("ColWidths[0] = %d, want %d (minColWidth floor)", l.ColWidths[0], minColWidth)
69
- }
70
- }
71
-
72
- func TestCalculateLayout_tinyHeight_floorsAtMinContentHeight(t *testing.T) {
73
- l := CalculateLayout(100, 8)
74
- if l.ContentHeight != minContentHeight {
75
- t.Errorf("ContentHeight = %d, want %d", l.ContentHeight, minContentHeight)
76
- }
77
- }
78
-
79
- func TestCalculateLayoutWithChrome_accountsForExtraHeaderLine(t *testing.T) {
80
- l := CalculateLayoutWithChrome(120, 40, 1)
81
- if l.ContentHeight != 29 {
82
- t.Errorf("ContentHeight = %d, want 29", l.ContentHeight)
83
- }
84
- }
85
-
86
- func TestCalculateLayout_breakpointBoundaries(t *testing.T) {
87
- cases := []struct {
88
- width int
89
- wantColCount int
90
- wantEpic bool
91
- }{
92
- {119, 3, false},
93
- {120, 3, true},
94
- {79, 1, false},
95
- {80, 3, false},
96
- }
97
- for _, tc := range cases {
98
- l := CalculateLayout(tc.width, 40)
99
- if l.ColCount != tc.wantColCount {
100
- t.Errorf("width=%d: ColCount = %d, want %d", tc.width, l.ColCount, tc.wantColCount)
101
- }
102
- if l.EpicPanelVisible != tc.wantEpic {
103
- t.Errorf("width=%d: EpicPanelVisible = %v, want %v", tc.width, l.EpicPanelVisible, tc.wantEpic)
104
- }
105
- }
106
- }
@@ -1,235 +0,0 @@
1
- package board
2
-
3
- import (
4
- tea "github.com/charmbracelet/bubbletea"
5
- "github.com/fsnotify/fsnotify"
6
- "github.com/opencode/savepoint/internal/data"
7
- )
8
-
9
- type OverlayType string
10
-
11
- const (
12
- OverlayNone OverlayType = ""
13
- OverlayHelp OverlayType = "help"
14
- OverlayEpic OverlayType = "epic"
15
- OverlayRelease OverlayType = "release"
16
- OverlayDetail OverlayType = "detail"
17
- OverlayEpicDetail OverlayType = "detail-epic"
18
- )
19
-
20
- // ViewConfig holds terminal and overlay presentation state.
21
- type ViewConfig struct {
22
- Theme data.Theme
23
- Overlay OverlayType
24
- Width int
25
- Height int
26
- StatusMessage string
27
- }
28
-
29
- // DataState holds task, router, and filesystem state used by the board.
30
- type DataState struct {
31
- AllTasks []data.Task
32
- Tasks map[data.ColumnType][]data.Task
33
- Root string
34
- EpicStatus map[string]string
35
- RouterTask string
36
- RouterState *data.RouterState
37
- Watcher *fsnotify.Watcher
38
- }
39
-
40
- // NavigationState holds board-column and detail scrolling state.
41
- type NavigationState struct {
42
- FocusedColumn data.ColumnType
43
- FocusedTask int
44
- ColumnOffsets map[data.ColumnType]int
45
- DetailOffset int
46
- }
47
-
48
- // EpicState holds epic list, sidebar, and detail overlay state.
49
- type EpicState struct {
50
- SelectedEpic string
51
- Epics []string
52
- EpicCursor int
53
- EpicPanelFocus bool
54
- EpicPanelCursor int
55
- EpicDetailOffset int
56
- EpicDetailEpic string
57
- EpicDetailContent string
58
- EpicDetailTab int // 0=Detail, 1=Audit
59
- EpicAuditContent string // cached E##-Audit.md content
60
- }
61
-
62
- // ReleaseState holds release list and release picker state.
63
- type ReleaseState struct {
64
- SelectedRelease string
65
- Releases []string
66
- ReleaseEpics map[string][]string
67
- ReleaseCursor int
68
- }
69
-
70
- // DataAccessState holds board data-access implementations.
71
- type DataAccessState struct {
72
- Dependencies ModelDependencies
73
- }
74
-
75
- // Model holds all board state. Tasks are grouped by column for O(1) column access.
76
- type Model struct {
77
- ViewConfig
78
- DataState
79
- NavigationState
80
- EpicState
81
- ReleaseState
82
- DataAccessState
83
- }
84
-
85
- // NewModel groups tasks by column and returns an initialized Model.
86
- func NewModel(tasks []data.Task, release, epic string, deps ...ModelDependencies) Model {
87
- m := Model{
88
- ViewConfig: ViewConfig{
89
- Overlay: OverlayNone,
90
- },
91
- DataState: DataState{
92
- AllTasks: append([]data.Task(nil), tasks...),
93
- },
94
- NavigationState: NavigationState{
95
- FocusedColumn: data.ColumnPlanned,
96
- FocusedTask: 0,
97
- ColumnOffsets: newColumnOffsets(),
98
- },
99
- EpicState: EpicState{
100
- SelectedEpic: epic,
101
- },
102
- ReleaseState: ReleaseState{
103
- SelectedRelease: release,
104
- },
105
- DataAccessState: DataAccessState{
106
- Dependencies: modelDependencies(deps),
107
- },
108
- }
109
- m.refreshTasks()
110
- return m
111
- }
112
-
113
- func (m Model) Init() tea.Cmd {
114
- if m.Watcher == nil {
115
- return nil
116
- }
117
- return watchFiles(m.Watcher)
118
- }
119
-
120
- func groupedTasks(tasks []data.Task) map[data.ColumnType][]data.Task {
121
- grouped := map[data.ColumnType][]data.Task{
122
- data.ColumnPlanned: {},
123
- data.ColumnInProgress: {},
124
- data.ColumnDone: {},
125
- }
126
- for _, t := range tasks {
127
- col := t.Column
128
- if col == "" {
129
- col = data.ColumnPlanned
130
- }
131
- grouped[col] = append(grouped[col], t)
132
- }
133
- return grouped
134
- }
135
-
136
- func (m *Model) refreshTasks() {
137
- visible := make([]data.Task, 0, len(m.AllTasks))
138
- for _, t := range m.AllTasks {
139
- if m.SelectedRelease != "" && t.Release != "" && t.Release != m.SelectedRelease {
140
- continue
141
- }
142
- if m.SelectedEpic != "" && t.Epic != "" && t.Epic != m.SelectedEpic {
143
- continue
144
- }
145
- visible = append(visible, t)
146
- }
147
- m.Tasks = groupedTasks(visible)
148
- m.clampFocusedTask()
149
- m.clampColumnOffsets()
150
- }
151
-
152
- func newColumnOffsets() map[data.ColumnType]int {
153
- return map[data.ColumnType]int{
154
- data.ColumnPlanned: 0,
155
- data.ColumnInProgress: 0,
156
- data.ColumnDone: 0,
157
- }
158
- }
159
-
160
- func (m *Model) refreshEpicsForRelease() {
161
- if len(m.ReleaseEpics) == 0 {
162
- return
163
- }
164
-
165
- epics := m.ReleaseEpics[m.SelectedRelease]
166
- m.Epics = append([]string(nil), epics...)
167
- if len(m.Epics) == 0 {
168
- m.SelectedEpic = ""
169
- m.EpicCursor = 0
170
- m.EpicPanelCursor = 0
171
- m.EpicPanelFocus = false
172
- return
173
- }
174
-
175
- for _, epic := range m.Epics {
176
- if epic == m.SelectedEpic {
177
- m.EpicCursor = sliceIndex(m.Epics, m.SelectedEpic)
178
- m.clampEpicPanelCursor()
179
- return
180
- }
181
- }
182
-
183
- m.SelectedEpic = m.Epics[0]
184
- m.EpicCursor = 0
185
- m.clampEpicPanelCursor()
186
- }
187
-
188
- func (m *Model) clampEpicPanelCursor() {
189
- if len(m.Epics) == 0 {
190
- m.EpicPanelCursor = 0
191
- m.EpicPanelFocus = false
192
- return
193
- }
194
- if m.EpicPanelCursor >= len(m.Epics) {
195
- m.EpicPanelCursor = len(m.Epics) - 1
196
- }
197
- if m.EpicPanelCursor < 0 {
198
- m.EpicPanelCursor = 0
199
- }
200
- }
201
-
202
- func (m *Model) clampFocusedTask() {
203
- tasks := m.Tasks[m.FocusedColumn]
204
- if len(tasks) == 0 {
205
- m.FocusedTask = 0
206
- return
207
- }
208
- if m.FocusedTask >= len(tasks) {
209
- m.FocusedTask = len(tasks) - 1
210
- }
211
- if m.FocusedTask < 0 {
212
- m.FocusedTask = 0
213
- }
214
- }
215
-
216
- func (m *Model) clampColumnOffsets() {
217
- if m.ColumnOffsets == nil {
218
- m.ColumnOffsets = newColumnOffsets()
219
- }
220
- for _, col := range columnOrder {
221
- tasks := m.Tasks[col]
222
- offset := m.ColumnOffsets[col]
223
- if offset < 0 || len(tasks) == 0 {
224
- m.ColumnOffsets[col] = 0
225
- continue
226
- }
227
- if offset >= len(tasks) {
228
- m.ColumnOffsets[col] = len(tasks) - 1
229
- }
230
- }
231
- }
232
-
233
- func taskDone(task data.Task) bool {
234
- return task.Column == data.ColumnDone
235
- }
@@ -1,67 +0,0 @@
1
- package board
2
-
3
- import (
4
- "testing"
5
-
6
- "github.com/opencode/savepoint/internal/data"
7
- )
8
-
9
- func TestNewModel_emptyTasks(t *testing.T) {
10
- m := NewModel(nil, "v1", "E03")
11
-
12
- if m.SelectedRelease != "v1" {
13
- t.Errorf("SelectedRelease = %q, want %q", m.SelectedRelease, "v1")
14
- }
15
- if m.SelectedEpic != "E03" {
16
- t.Errorf("SelectedEpic = %q, want %q", m.SelectedEpic, "E03")
17
- }
18
- if m.FocusedColumn != data.ColumnPlanned {
19
- t.Errorf("FocusedColumn = %q, want %q", m.FocusedColumn, data.ColumnPlanned)
20
- }
21
- if m.FocusedTask != 0 {
22
- t.Errorf("FocusedTask = %d, want 0", m.FocusedTask)
23
- }
24
- if m.Overlay != OverlayNone {
25
- t.Errorf("Overlay = %q, want empty", m.Overlay)
26
- }
27
- for _, col := range []data.ColumnType{data.ColumnPlanned, data.ColumnInProgress, data.ColumnDone} {
28
- if _, ok := m.Tasks[col]; !ok {
29
- t.Errorf("Tasks missing column %q", col)
30
- }
31
- }
32
- }
33
-
34
- func TestNewModel_groupsByColumn(t *testing.T) {
35
- tasks := []data.Task{
36
- {ID: "T1", Column: data.ColumnPlanned},
37
- {ID: "T2", Column: data.ColumnInProgress},
38
- {ID: "T3", Column: data.ColumnDone},
39
- {ID: "T4", Column: data.ColumnPlanned},
40
- }
41
- m := NewModel(tasks, "v1", "E03")
42
-
43
- if got := len(m.Tasks[data.ColumnPlanned]); got != 2 {
44
- t.Errorf("Planned count = %d, want 2", got)
45
- }
46
- if got := len(m.Tasks[data.ColumnInProgress]); got != 1 {
47
- t.Errorf("InProgress count = %d, want 1", got)
48
- }
49
- if got := len(m.Tasks[data.ColumnDone]); got != 1 {
50
- t.Errorf("Done count = %d, want 1", got)
51
- }
52
- }
53
-
54
- func TestNewModel_emptyColumnDefaultsToPlanned(t *testing.T) {
55
- tasks := []data.Task{{ID: "T1"}}
56
- m := NewModel(tasks, "v1", "E03")
57
-
58
- if got := len(m.Tasks[data.ColumnPlanned]); got != 1 {
59
- t.Errorf("Planned count = %d, want 1 (empty column defaulted)", got)
60
- }
61
- }
62
-
63
- func TestModel_Init(t *testing.T) {
64
- m := NewModel(nil, "v1", "E03")
65
- // Init must not panic and returns a valid Cmd (nil or batch).
66
- _ = m.Init()
67
- }
@@ -1,88 +0,0 @@
1
- package board
2
-
3
- import (
4
- "fmt"
5
- "os"
6
- "path/filepath"
7
- "strings"
8
-
9
- "github.com/opencode/savepoint/internal/data"
10
- )
11
-
12
- const plainNonTTYWarning = "[non-interactive mode — run in a TTY to launch the board UI]"
13
- const plainAuditSignal = "[◆ audit proposals pending]"
14
-
15
- // RenderPlainTable renders a plain text three-column task table for non-TTY output.
16
- func RenderPlainTable(model Model) string {
17
- var b strings.Builder
18
-
19
- fmt.Fprintln(&b, plainNonTTYWarning)
20
- if hasAuditProposals(model.Root) {
21
- fmt.Fprintln(&b, plainAuditSignal)
22
- }
23
- fmt.Fprintln(&b)
24
-
25
- cols := []struct {
26
- label string
27
- col data.ColumnType
28
- }{
29
- {"PLANNED", data.ColumnPlanned},
30
- {"IN PROGRESS", data.ColumnInProgress},
31
- {"DONE", data.ColumnDone},
32
- }
33
-
34
- for _, c := range cols {
35
- tasks := model.Tasks[c.col]
36
- fmt.Fprintln(&b, c.label)
37
- if len(tasks) == 0 {
38
- fmt.Fprintln(&b, " (none)")
39
- }
40
- for _, t := range tasks {
41
- title := t.Title
42
- if title == "" {
43
- title = "(no title)"
44
- }
45
- fmt.Fprintf(&b, " %-52s %s\n", t.ID, title)
46
- }
47
- fmt.Fprintln(&b)
48
- }
49
-
50
- return b.String()
51
- }
52
-
53
- // hasAuditProposals reports whether any audit file under root contains a Proposed Changes section.
54
- func hasAuditProposals(root string) bool {
55
- releasesDir := filepath.Join(root, "releases")
56
- releases, err := os.ReadDir(releasesDir)
57
- if err != nil {
58
- return false
59
- }
60
- for _, r := range releases {
61
- if !r.IsDir() {
62
- continue
63
- }
64
- epicsDir := filepath.Join(releasesDir, r.Name(), "epics")
65
- epics, err := os.ReadDir(epicsDir)
66
- if err != nil {
67
- continue
68
- }
69
- for _, e := range epics {
70
- if !e.IsDir() {
71
- continue
72
- }
73
- short := e.Name()
74
- if idx := strings.Index(short, "-"); idx >= 0 {
75
- short = short[:idx]
76
- }
77
- auditPath := filepath.Join(epicsDir, e.Name(), short+"-Audit.md")
78
- raw, err := os.ReadFile(auditPath)
79
- if err != nil {
80
- continue
81
- }
82
- if strings.Contains(string(raw), "## Proposed Changes") {
83
- return true
84
- }
85
- }
86
- }
87
- return false
88
- }
@@ -1,117 +0,0 @@
1
- package board
2
-
3
- import (
4
- "os"
5
- "path/filepath"
6
- "strings"
7
- "testing"
8
-
9
- "github.com/opencode/savepoint/internal/data"
10
- )
11
-
12
- func TestRenderPlainTable_warningBanner(t *testing.T) {
13
- m := NewModel(nil, "", "")
14
- got := RenderPlainTable(m)
15
- if !strings.Contains(got, plainNonTTYWarning) {
16
- t.Errorf("RenderPlainTable missing warning banner, got:\n%s", got)
17
- }
18
- }
19
-
20
- func TestRenderPlainTable_columnHeaders(t *testing.T) {
21
- m := NewModel(nil, "", "")
22
- got := RenderPlainTable(m)
23
- for _, header := range []string{"PLANNED", "IN PROGRESS", "DONE"} {
24
- if !strings.Contains(got, header) {
25
- t.Errorf("RenderPlainTable missing column header %q", header)
26
- }
27
- }
28
- }
29
-
30
- func TestRenderPlainTable_taskIDsAndTitles(t *testing.T) {
31
- tasks := []data.Task{
32
- {ID: "E08/T001", Title: "CLI entrypoint", Column: data.ColumnDone},
33
- {ID: "E08/T002", Title: "Non-TTY fallback", Column: data.ColumnInProgress},
34
- {ID: "E08/T003", Title: "TUI app shell", Column: data.ColumnPlanned},
35
- }
36
- m := NewModel(tasks, "", "")
37
- got := RenderPlainTable(m)
38
-
39
- for _, want := range []string{"E08/T001", "CLI entrypoint", "E08/T002", "Non-TTY fallback", "E08/T003", "TUI app shell"} {
40
- if !strings.Contains(got, want) {
41
- t.Errorf("RenderPlainTable missing %q", want)
42
- }
43
- }
44
- }
45
-
46
- func TestRenderPlainTable_noneWhenColumnEmpty(t *testing.T) {
47
- m := NewModel(nil, "", "")
48
- got := RenderPlainTable(m)
49
- if !strings.Contains(got, "(none)") {
50
- t.Errorf("RenderPlainTable should show (none) for empty columns")
51
- }
52
- }
53
-
54
- func TestRenderPlainTable_auditSignalWhenProposalsExist(t *testing.T) {
55
- root := t.TempDir()
56
- epicDir := filepath.Join(root, "releases", "v1", "epics", "E01-test")
57
- if err := os.MkdirAll(epicDir, 0755); err != nil {
58
- t.Fatal(err)
59
- }
60
- auditContent := "---\ntype: audit\n---\n## Main Findings\nOK\n\n## Proposed Changes\n\n### Target File\nfoo.go\n"
61
- if err := os.WriteFile(filepath.Join(epicDir, "E01-Audit.md"), []byte(auditContent), 0644); err != nil {
62
- t.Fatal(err)
63
- }
64
-
65
- m := NewModel(nil, "", "")
66
- m.Root = root
67
- got := RenderPlainTable(m)
68
- if !strings.Contains(got, plainAuditSignal) {
69
- t.Errorf("RenderPlainTable missing audit signal when proposals exist, got:\n%s", got)
70
- }
71
- }
72
-
73
- func TestRenderPlainTable_noAuditSignalWhenNone(t *testing.T) {
74
- root := t.TempDir()
75
- m := NewModel(nil, "", "")
76
- m.Root = root
77
- got := RenderPlainTable(m)
78
- if strings.Contains(got, plainAuditSignal) {
79
- t.Errorf("RenderPlainTable should not show audit signal when no proposals exist")
80
- }
81
- }
82
-
83
- func TestHasAuditProposals_detectsSection(t *testing.T) {
84
- root := t.TempDir()
85
- epicDir := filepath.Join(root, "releases", "v1", "epics", "E02-slug")
86
- if err := os.MkdirAll(epicDir, 0755); err != nil {
87
- t.Fatal(err)
88
- }
89
- content := "## Main Findings\nAll good.\n\n## Proposed Changes\n\n### Target File\nbar.go\n"
90
- if err := os.WriteFile(filepath.Join(epicDir, "E02-Audit.md"), []byte(content), 0644); err != nil {
91
- t.Fatal(err)
92
- }
93
- if !hasAuditProposals(root) {
94
- t.Error("hasAuditProposals should return true when Proposed Changes section exists")
95
- }
96
- }
97
-
98
- func TestHasAuditProposals_noProposals(t *testing.T) {
99
- root := t.TempDir()
100
- epicDir := filepath.Join(root, "releases", "v1", "epics", "E03-slug")
101
- if err := os.MkdirAll(epicDir, 0755); err != nil {
102
- t.Fatal(err)
103
- }
104
- content := "## Main Findings\nAll good.\n"
105
- if err := os.WriteFile(filepath.Join(epicDir, "E03-Audit.md"), []byte(content), 0644); err != nil {
106
- t.Fatal(err)
107
- }
108
- if hasAuditProposals(root) {
109
- t.Error("hasAuditProposals should return false when no Proposed Changes section")
110
- }
111
- }
112
-
113
- func TestHasAuditProposals_missingRoot(t *testing.T) {
114
- if hasAuditProposals("/nonexistent/path/xyz") {
115
- t.Error("hasAuditProposals should return false for missing root")
116
- }
117
- }
@@ -1,34 +0,0 @@
1
- package board
2
-
3
- import (
4
- "strings"
5
-
6
- "github.com/opencode/savepoint/internal/styles"
7
- )
8
-
9
- const releaseActiveMarker = "►"
10
-
11
- // RenderReleaseDropdown renders the release selection dropdown overlay.
12
- func RenderReleaseDropdown(releases []string, cursor int, width int) string {
13
- inner := width - epicPanelOverhead
14
- if inner < 2 {
15
- inner = 2
16
- }
17
-
18
- lines := []string{styles.ColumnTitleFocused.Render("SELECT RELEASE"), strings.Repeat("─", inner)}
19
- for i, r := range releases {
20
- label := truncate(r, inner-2)
21
- if i == cursor {
22
- lines = append(lines, styles.TaskItemFocused.Render(releaseActiveMarker+" "+label))
23
- } else {
24
- lines = append(lines, styles.TaskItem.Render(" "+label))
25
- }
26
- }
27
- if len(releases) == 0 {
28
- lines = append(lines, styles.TaskItem.Render("(none)"))
29
- }
30
- lines = append(lines, "", styles.CardMeta.Render("↑↓:nav enter:select esc:cancel"))
31
- return styles.EpicPanel.Width(width).Render(strings.Join(lines, "\n"))
32
- }
33
-
34
-