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,556 +0,0 @@
1
- package board
2
-
3
- import (
4
- "os"
5
- "path/filepath"
6
- "strings"
7
-
8
- tea "github.com/charmbracelet/bubbletea"
9
- "github.com/opencode/savepoint/internal/data"
10
- )
11
-
12
- var columnOrder = []data.ColumnType{
13
- data.ColumnPlanned,
14
- data.ColumnInProgress,
15
- data.ColumnDone,
16
- }
17
-
18
- func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
19
- switch msg := msg.(type) {
20
- case fileChangeMsg:
21
- if m.Root != "" {
22
- return m, reloadTasks(m.Root, m.Dependencies)
23
- }
24
- case reloadMsg:
25
- m.AllTasks = msg.tasks
26
- m.Releases = append([]string(nil), msg.releases...)
27
- m.ReleaseEpics = copyReleaseEpics(msg.releaseEpics)
28
- m.EpicStatus = msg.epicStatuses
29
- if msg.routerState != nil {
30
- m.RouterState = msg.routerState
31
- m.RouterTask = msg.routerState.Task
32
- }
33
- m.SelectedRelease = firstKnown(m.SelectedRelease, m.Releases)
34
- m.refreshEpicsForRelease()
35
- m.refreshTasks()
36
- m.ensureFocusedTaskVisible()
37
- if m.Watcher != nil {
38
- return m, watchFiles(m.Watcher)
39
- }
40
- case tea.KeyMsg:
41
- if m.Overlay != OverlayNone {
42
- return m.handleOverlay(msg)
43
- }
44
- return m.handleBoardKey(msg)
45
- case tea.WindowSizeMsg:
46
- m.Width = msg.Width
47
- m.Height = msg.Height
48
- if !m.epicPanelAvailable() {
49
- m.EpicPanelFocus = false
50
- }
51
- m.ensureFocusedTaskVisible()
52
- case routerWriteMsg:
53
- m.StatusMessage = msg.message
54
- m.RouterState = msg.state
55
- m.RouterTask = msg.taskID
56
- case taskWriteMsg:
57
- for i, t := range m.AllTasks {
58
- if t.ID == msg.next.ID {
59
- m.AllTasks[i] = msg.next
60
- break
61
- }
62
- }
63
- m.StatusMessage = taskTransitionMessage(msg.prefix, msg.next)
64
- m.refreshTasks()
65
- m.ensureFocusedTaskVisible()
66
- case epicDetailMsg:
67
- m.EpicDetailContent = msg.content
68
- case auditContentMsg:
69
- m.EpicAuditContent = msg.content
70
- case errorMsg:
71
- m.StatusMessage = msg.message
72
- }
73
- return m, nil
74
- }
75
-
76
- func (m Model) handleOverlay(msg tea.KeyMsg) (tea.Model, tea.Cmd) {
77
- switch m.Overlay {
78
- case OverlayHelp:
79
- return m.handleHelpOverlay(msg)
80
- case OverlayEpic:
81
- return m.handleEpicOverlay(msg)
82
- case OverlayRelease:
83
- return m.handleReleaseOverlay(msg)
84
- case OverlayDetail:
85
- return m.handleDetailOverlay(msg)
86
- case OverlayEpicDetail:
87
- return m.handleEpicDetailOverlay(msg)
88
- }
89
- return m, nil
90
- }
91
-
92
- func (m Model) handleBoardKey(msg tea.KeyMsg) (tea.Model, tea.Cmd) {
93
- switch msg.String() {
94
- case "q", "ctrl+c":
95
- if m.Watcher != nil {
96
- m.Watcher.Close()
97
- }
98
- return m, tea.Quit
99
- case "e":
100
- m.Overlay = OverlayEpic
101
- m.EpicCursor = sliceIndex(m.Epics, m.SelectedEpic)
102
- return m, nil
103
- case "r":
104
- m.Overlay = OverlayRelease
105
- m.ReleaseCursor = sliceIndex(m.Releases, m.SelectedRelease)
106
- return m, nil
107
- case "?":
108
- m.Overlay = OverlayHelp
109
- return m, nil
110
- case "p":
111
- task, ok := m.focusedTask()
112
- if !ok {
113
- return m, nil
114
- }
115
- if taskDone(task) {
116
- m.StatusMessage = "Router not updated: focused task is done"
117
- return m, nil
118
- }
119
- if m.Root == "" {
120
- m.StatusMessage = "Router not updated: no savepoint root"
121
- return m, nil
122
- }
123
- return m, writeRouterTaskCmd(m.Root, task, m.Dependencies.RouterReader)
124
- }
125
- if m.EpicPanelFocus {
126
- if !m.epicPanelAvailable() {
127
- m.EpicPanelFocus = false
128
- } else {
129
- return m.updateEpicPanel(msg)
130
- }
131
- }
132
- switch msg.String() {
133
- case "left", "h":
134
- if m.FocusedColumn == data.ColumnPlanned && m.epicPanelAvailable() {
135
- m.EpicPanelFocus = true
136
- m.EpicPanelCursor = sliceIndex(m.Epics, m.SelectedEpic)
137
- m.StatusMessage = ""
138
- return m, nil
139
- }
140
- m.FocusedColumn = prevColumn(m.FocusedColumn)
141
- m.FocusedTask = 0
142
- m.ensureFocusedTaskVisible()
143
- m.StatusMessage = ""
144
- case "right", "l":
145
- m.FocusedColumn = nextColumn(m.FocusedColumn)
146
- m.FocusedTask = 0
147
- m.ensureFocusedTaskVisible()
148
- m.StatusMessage = ""
149
- case "up", "k":
150
- if m.FocusedTask > 0 {
151
- m.FocusedTask--
152
- }
153
- m.ensureFocusedTaskVisible()
154
- m.StatusMessage = ""
155
- case "down", "j":
156
- if m.FocusedTask < len(m.Tasks[m.FocusedColumn])-1 {
157
- m.FocusedTask++
158
- }
159
- m.ensureFocusedTaskVisible()
160
- m.StatusMessage = ""
161
- case "pgup":
162
- m.scrollFocusedColumn(-m.columnPageSize())
163
- m.StatusMessage = ""
164
- case "pgdown":
165
- m.scrollFocusedColumn(m.columnPageSize())
166
- m.StatusMessage = ""
167
- case "enter":
168
- tasks := m.Tasks[m.FocusedColumn]
169
- if len(tasks) > 0 && m.FocusedTask < len(tasks) {
170
- m.Overlay = OverlayDetail
171
- m.DetailOffset = 0
172
- }
173
- m.StatusMessage = ""
174
- case " ":
175
- return m.handleAdvanceTask()
176
- case "backspace":
177
- return m.handleRetreatTask()
178
- }
179
- return m, nil
180
- }
181
-
182
- func (m Model) handleAdvanceTask() (tea.Model, tea.Cmd) {
183
- tasks := m.Tasks[m.FocusedColumn]
184
- if len(tasks) > 0 && m.FocusedTask < len(tasks) {
185
- task := tasks[m.FocusedTask]
186
- if ok, reason := CanAdvance(&task, m.AllTasks); !ok {
187
- m.StatusMessage = reason
188
- return m, nil
189
- }
190
- m.StatusMessage = ""
191
- for i, t := range m.AllTasks {
192
- if t.ID == task.ID {
193
- next := m.AllTasks[i]
194
- Advance(&next)
195
- if next.Path != "" {
196
- return m, writeTaskStatusCmd(t, next, task.Mtime, "Moved")
197
- }
198
- m.AllTasks[i] = next
199
- m.StatusMessage = taskTransitionMessage("Moved", next)
200
- break
201
- }
202
- }
203
- m.refreshTasks()
204
- m.ensureFocusedTaskVisible()
205
- }
206
- return m, nil
207
- }
208
-
209
- func (m Model) handleRetreatTask() (tea.Model, tea.Cmd) {
210
- tasks := m.Tasks[m.FocusedColumn]
211
- if len(tasks) > 0 && m.FocusedTask < len(tasks) {
212
- task := tasks[m.FocusedTask]
213
- m.StatusMessage = ""
214
- for i, t := range m.AllTasks {
215
- if t.ID == task.ID {
216
- next := m.AllTasks[i]
217
- Retreat(&next)
218
- if next.Path != "" {
219
- return m, writeTaskStatusCmd(t, next, task.Mtime, "Moved back")
220
- }
221
- m.AllTasks[i] = next
222
- m.StatusMessage = taskTransitionMessage("Moved back", next)
223
- break
224
- }
225
- }
226
- m.refreshTasks()
227
- m.ensureFocusedTaskVisible()
228
- }
229
- return m, nil
230
- }
231
-
232
- func (m Model) handleHelpOverlay(msg tea.KeyMsg) (tea.Model, tea.Cmd) {
233
- switch msg.String() {
234
- case "esc", "q":
235
- m.Overlay = OverlayNone
236
- }
237
- return m, nil
238
- }
239
-
240
- func (m Model) handleEpicOverlay(msg tea.KeyMsg) (tea.Model, tea.Cmd) {
241
- switch msg.String() {
242
- case "esc", "q":
243
- m.Overlay = OverlayNone
244
- case "up", "k":
245
- if m.EpicCursor > 0 {
246
- m.EpicCursor--
247
- }
248
- case "down", "j":
249
- if len(m.Epics) > 0 && m.EpicCursor < len(m.Epics)-1 {
250
- m.EpicCursor++
251
- }
252
- case "enter":
253
- if len(m.Epics) > 0 {
254
- m.SelectedEpic = m.Epics[m.EpicCursor]
255
- m.FocusedTask = 0
256
- m.DetailOffset = 0
257
- m.refreshTasks()
258
- m.ensureFocusedTaskVisible()
259
- m.Overlay = OverlayNone
260
- if m.Root != "" {
261
- return m, writeRouterReleaseEpicCmd(m.Root, m.SelectedEpic, m.SelectedRelease, m.Dependencies.RouterReader)
262
- }
263
- }
264
- }
265
- return m, nil
266
- }
267
-
268
- func (m Model) handleReleaseOverlay(msg tea.KeyMsg) (tea.Model, tea.Cmd) {
269
- switch msg.String() {
270
- case "esc", "q":
271
- m.Overlay = OverlayNone
272
- case "up", "k":
273
- if m.ReleaseCursor > 0 {
274
- m.ReleaseCursor--
275
- }
276
- case "down", "j":
277
- if len(m.Releases) > 0 && m.ReleaseCursor < len(m.Releases)-1 {
278
- m.ReleaseCursor++
279
- }
280
- case "enter":
281
- if len(m.Releases) > 0 {
282
- m.SelectedRelease = m.Releases[m.ReleaseCursor]
283
- m.refreshEpicsForRelease()
284
- m.FocusedTask = 0
285
- m.DetailOffset = 0
286
- m.refreshTasks()
287
- m.ensureFocusedTaskVisible()
288
- m.Overlay = OverlayNone
289
- if m.Root != "" {
290
- return m, writeRouterReleaseEpicCmd(m.Root, m.SelectedEpic, m.SelectedRelease, m.Dependencies.RouterReader)
291
- }
292
- }
293
- }
294
- return m, nil
295
- }
296
-
297
- func (m Model) handleDetailOverlay(msg tea.KeyMsg) (tea.Model, tea.Cmd) {
298
- switch msg.String() {
299
- case "esc", "q":
300
- m.Overlay = OverlayNone
301
- case "up", "k":
302
- if m.DetailOffset > 0 {
303
- m.DetailOffset--
304
- }
305
- case "down", "j":
306
- m.DetailOffset++
307
- case "pgup":
308
- m.DetailOffset -= m.detailPageSize()
309
- if m.DetailOffset < 0 {
310
- m.DetailOffset = 0
311
- }
312
- case "pgdown":
313
- m.DetailOffset += m.detailPageSize()
314
- }
315
- return m, nil
316
- }
317
-
318
- func (m Model) handleEpicDetailOverlay(msg tea.KeyMsg) (tea.Model, tea.Cmd) {
319
- switch msg.String() {
320
- case "esc", "q":
321
- m.Overlay = OverlayNone
322
- case "1":
323
- m.EpicDetailTab = 0
324
- m.EpicDetailOffset = 0
325
- case "2":
326
- m.EpicDetailTab = 1
327
- m.EpicDetailOffset = 0
328
- if m.EpicAuditContent == "" {
329
- epicSlug := m.epicDetailEpic()
330
- shortEpicID := epicSlug
331
- if idx := strings.Index(epicSlug, "-"); idx >= 0 {
332
- shortEpicID = epicSlug[:idx]
333
- }
334
- epicDir := filepath.Join(m.Root, "releases", m.SelectedRelease, "epics", epicSlug)
335
- return m, readEpicAuditCmd(epicDir, shortEpicID)
336
- }
337
- case "up", "k":
338
- if m.EpicDetailOffset > 0 {
339
- m.EpicDetailOffset--
340
- }
341
- case "down", "j":
342
- m.EpicDetailOffset++
343
- case "pgup":
344
- m.EpicDetailOffset -= m.detailPageSize()
345
- if m.EpicDetailOffset < 0 {
346
- m.EpicDetailOffset = 0
347
- }
348
- case "pgdown":
349
- m.EpicDetailOffset += m.detailPageSize()
350
- }
351
- return m, nil
352
- }
353
-
354
- func taskWriteErrorMessage(err error) string {
355
- if err == data.ErrMtimeConflict {
356
- return "mtime conflict: refresh before retrying"
357
- }
358
- return err.Error()
359
- }
360
-
361
- func (m Model) updateEpicPanel(msg tea.KeyMsg) (tea.Model, tea.Cmd) {
362
- if len(m.Epics) == 0 {
363
- m.EpicPanelFocus = false
364
- return m, nil
365
- }
366
-
367
- m.StatusMessage = ""
368
- switch msg.String() {
369
- case "up", "k":
370
- if m.EpicPanelCursor > 0 {
371
- m.EpicPanelCursor--
372
- return m, m.selectEpicPanelEpic()
373
- }
374
- case "down", "j":
375
- if m.EpicPanelCursor < len(m.Epics)-1 {
376
- m.EpicPanelCursor++
377
- return m, m.selectEpicPanelEpic()
378
- }
379
- case "enter":
380
- return m, m.openEpicDetailOverlay()
381
- case "right", "l":
382
- m.EpicPanelFocus = false
383
- m.FocusedColumn = data.ColumnPlanned
384
- m.FocusedTask = 0
385
- m.ensureFocusedTaskVisible()
386
- case "left", "h":
387
- }
388
- return m, nil
389
- }
390
-
391
- func (m *Model) selectEpicPanelEpic() tea.Cmd {
392
- if len(m.Epics) == 0 || m.EpicPanelCursor < 0 || m.EpicPanelCursor >= len(m.Epics) {
393
- return nil
394
- }
395
- m.SelectedEpic = m.Epics[m.EpicPanelCursor]
396
- m.FocusedTask = 0
397
- m.DetailOffset = 0
398
- m.refreshTasks()
399
- m.ensureFocusedTaskVisible()
400
- if m.Root != "" {
401
- return writeRouterReleaseEpicCmd(m.Root, m.SelectedEpic, m.SelectedRelease, m.Dependencies.RouterReader)
402
- }
403
- return nil
404
- }
405
-
406
- func (m *Model) openEpicDetailOverlay() tea.Cmd {
407
- if len(m.Epics) == 0 || m.EpicPanelCursor < 0 || m.EpicPanelCursor >= len(m.Epics) {
408
- return nil
409
- }
410
- epicSlug := m.Epics[m.EpicPanelCursor]
411
- shortEpicID := epicSlug
412
- if idx := strings.Index(epicSlug, "-"); idx >= 0 {
413
- shortEpicID = epicSlug[:idx]
414
- }
415
- epicDir := filepath.Join(m.Root, "releases", m.SelectedRelease, "epics", epicSlug)
416
- m.EpicDetailEpic = epicSlug
417
- m.EpicDetailOffset = 0
418
- m.EpicDetailTab = 0
419
- m.EpicAuditContent = ""
420
- m.Overlay = OverlayEpicDetail
421
- return readEpicDetailCmd(epicDir, shortEpicID)
422
- }
423
-
424
- func readEpicDetailFile(epicDir, shortID string) string {
425
- for _, suffix := range []string{"-Detail.md", "-Design.md"} {
426
- if raw, err := os.ReadFile(filepath.Join(epicDir, shortID+suffix)); err == nil {
427
- return string(raw)
428
- }
429
- }
430
- entries, err := os.ReadDir(epicDir)
431
- if err != nil {
432
- return "(no detail available)"
433
- }
434
- prefix := shortID + "-"
435
- for _, e := range entries {
436
- if !e.IsDir() && strings.HasPrefix(e.Name(), prefix) && strings.HasSuffix(e.Name(), ".md") {
437
- if raw, err := os.ReadFile(filepath.Join(epicDir, e.Name())); err == nil {
438
- return string(raw)
439
- }
440
- }
441
- }
442
- return "(no detail available)"
443
- }
444
-
445
- func copyReleaseEpics(in map[string][]string) map[string][]string {
446
- out := make(map[string][]string, len(in))
447
- for release, epics := range in {
448
- out[release] = append([]string(nil), epics...)
449
- }
450
- return out
451
- }
452
-
453
- func (m Model) epicDetailEpic() string {
454
- if m.EpicDetailEpic != "" {
455
- return m.EpicDetailEpic
456
- }
457
- if m.SelectedEpic != "" {
458
- return m.SelectedEpic
459
- }
460
- if len(m.Epics) > 0 && m.EpicPanelCursor >= 0 && m.EpicPanelCursor < len(m.Epics) {
461
- return m.Epics[m.EpicPanelCursor]
462
- }
463
- return ""
464
- }
465
-
466
- func (m *Model) ensureFocusedTaskVisible() {
467
- if m.ColumnOffsets == nil {
468
- m.ColumnOffsets = newColumnOffsets()
469
- }
470
- tasks := m.Tasks[m.FocusedColumn]
471
- if len(tasks) == 0 {
472
- m.ColumnOffsets[m.FocusedColumn] = 0
473
- return
474
- }
475
- pageSize := m.columnPageSize()
476
- offset := m.ColumnOffsets[m.FocusedColumn]
477
- if m.FocusedTask < offset {
478
- offset = m.FocusedTask
479
- }
480
- if m.FocusedTask >= offset+pageSize {
481
- offset = m.FocusedTask - pageSize + 1
482
- }
483
- maxOffset := max(len(tasks)-pageSize, 0)
484
- if offset > maxOffset {
485
- offset = maxOffset
486
- }
487
- if offset < 0 {
488
- offset = 0
489
- }
490
- m.ColumnOffsets[m.FocusedColumn] = offset
491
- }
492
-
493
- func (m *Model) scrollFocusedColumn(delta int) {
494
- if m.ColumnOffsets == nil {
495
- m.ColumnOffsets = newColumnOffsets()
496
- }
497
- tasks := m.Tasks[m.FocusedColumn]
498
- if len(tasks) == 0 {
499
- m.ColumnOffsets[m.FocusedColumn] = 0
500
- m.FocusedTask = 0
501
- return
502
- }
503
- pageSize := m.columnPageSize()
504
- maxOffset := max(len(tasks)-pageSize, 0)
505
- offset := m.ColumnOffsets[m.FocusedColumn] + delta
506
- if offset < 0 {
507
- offset = 0
508
- }
509
- if offset > maxOffset {
510
- offset = maxOffset
511
- }
512
- m.ColumnOffsets[m.FocusedColumn] = offset
513
- m.FocusedTask = min(offset, len(tasks)-1)
514
- }
515
-
516
- func (m Model) columnPageSize() int {
517
- h := m.Height
518
- if h == 0 {
519
- h = defaultTermH
520
- }
521
- return visibleColumnTaskLimit(CalculateLayout(m.Width, h).ContentHeight)
522
- }
523
-
524
- func (m Model) detailPageSize() int {
525
- return max(detailMaxHeight(m.Height)-3, 1)
526
- }
527
-
528
- func (m Model) epicPanelPageSize() int {
529
- h := m.Height
530
- if h == 0 {
531
- h = defaultTermH
532
- }
533
- return max(h/2, 1)
534
- }
535
-
536
- func (m Model) epicPanelAvailable() bool {
537
- return len(m.Epics) > 0 && CalculateLayout(m.Width, m.Height).EpicPanelVisible
538
- }
539
-
540
- func prevColumn(col data.ColumnType) data.ColumnType {
541
- for i, c := range columnOrder {
542
- if c == col {
543
- return columnOrder[(i+len(columnOrder)-1)%len(columnOrder)]
544
- }
545
- }
546
- return columnOrder[0]
547
- }
548
-
549
- func nextColumn(col data.ColumnType) data.ColumnType {
550
- for i, c := range columnOrder {
551
- if c == col {
552
- return columnOrder[(i+1)%len(columnOrder)]
553
- }
554
- }
555
- return columnOrder[0]
556
- }