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,330 +0,0 @@
1
- # Ink.js Gotchas & Common Problems
2
-
3
- ## Table of Contents
4
-
5
- 1. [Icon / Emoji Width Problems](#1-icon--emoji-width-problems)
6
- 2. [Ctrl+C Handling](#2-ctrlc-handling)
7
- 3. [useInput Conflicts](#3-useinput-conflicts)
8
- 4. [Enter Double-Fire](#4-enter-double-fire)
9
- 5. [CJK / Multi-Width Cursor](#5-cjk--multi-width-cursor)
10
- 6. [Layout Breaks](#6-layout-breaks)
11
- 7. [console.log Interference](#7-consolelog-interference)
12
- 8. [Ink Color Type Errors](#8-ink-color-type-errors)
13
-
14
- ---
15
-
16
- ## 1. Icon / Emoji Width Problems
17
-
18
- ### Problem
19
-
20
- `string-width` v8+ changed how Variation Selectors (VS15/VS16) are handled,
21
- causing emoji width calculations to be off. Terminals may render an emoji as
22
- 2 cells wide, but `stringWidth()` sometimes returns 1.
23
-
24
- ### Solution: WIDTH_OVERRIDES Pattern
25
-
26
- ```typescript
27
- import stringWidth from "string-width";
28
-
29
- const iconWidthOverrides: Record<string, number> = {
30
- "⚡": 1,
31
- "✨": 1,
32
- "🐛": 1,
33
- "🔥": 1,
34
- "🚀": 1,
35
- "📌": 1,
36
- "🟢": 1,
37
- "🟠": 1,
38
- "👉": 1,
39
- "💾": 1,
40
- "📤": 1,
41
- "🔃": 1,
42
- "✅": 1,
43
- "⚠️": 1,
44
- "🔗": 1,
45
- "💻": 1,
46
- "☁️": 1,
47
- };
48
-
49
- const getIconWidth = (icon: string): number => {
50
- const baseWidth = stringWidth(icon);
51
- const override = iconWidthOverrides[icon];
52
- return override !== undefined ? Math.max(baseWidth, override) : baseWidth;
53
- };
54
-
55
- // Fixed-width column padding
56
- const COLUMN_WIDTH = 2;
57
- const padIcon = (icon: string): string => {
58
- const width = getIconWidth(icon);
59
- const padding = Math.max(0, COLUMN_WIDTH - width);
60
- return icon + " ".repeat(padding);
61
- };
62
- ```
63
-
64
- ### Affected Areas
65
-
66
- - Status icon columns in board view
67
- - Progress indicators
68
- - Any fixed-width layout with inline symbols
69
-
70
- ---
71
-
72
- ## 2. Ctrl+C Handling
73
-
74
- ### Problem
75
-
76
- Ink handles `Ctrl+C` by default to exit the app. This can fire twice or
77
- conflict with custom cleanup logic.
78
-
79
- ### Solution: `exitOnCtrlC: false` + `useInput` + SIGINT
80
-
81
- ```typescript
82
- import { render, useApp, useInput } from "ink";
83
- import process from "node:process";
84
-
85
- function App({ onExit }: { onExit: () => void }) {
86
- const { exit } = useApp();
87
-
88
- useInput((input, key) => {
89
- if (key.ctrl && input === "c") {
90
- onExit();
91
- exit();
92
- }
93
- });
94
-
95
- // Also handle SIGINT directly
96
- useEffect(() => {
97
- const handler = () => {
98
- onExit();
99
- exit();
100
- };
101
- process.on("SIGINT", handler);
102
- return () => process.off("SIGINT", handler);
103
- }, [exit, onExit]);
104
-
105
- return <Box>...</Box>;
106
- }
107
-
108
- // Disable Ink's default Ctrl+C handler
109
- render(<App onExit={cleanup} />, { exitOnCtrlC: false });
110
- ```
111
-
112
- ---
113
-
114
- ## 3. useInput Conflicts
115
-
116
- ### Problem
117
-
118
- When multiple `useInput` hooks exist, **all handlers fire** for every keypress.
119
- A parent and child component may both process the same key.
120
-
121
- ### Solutions
122
-
123
- **Pattern 1: `disabled` prop**
124
-
125
- ```typescript
126
- useInput((input, key) => {
127
- if (disabled) return; // Ignore input when inactive
128
- // Handle key...
129
- });
130
- ```
131
-
132
- **Pattern 2: Mode flag**
133
-
134
- ```typescript
135
- const [filterMode, setFilterMode] = useState(false);
136
-
137
- useInput((input, key) => {
138
- if (filterMode) return; // Global shortcuts disabled while filtering
139
- if (input === "c") onCleanupCommand?.();
140
- });
141
- ```
142
-
143
- **Pattern 3: `blockKeys` prop on Input component**
144
-
145
- ```typescript
146
- // Inside an Input component
147
- useInput((input) => {
148
- if (blockKeys && blockKeys.includes(input)) {
149
- return; // Consume the key; do not propagate to parent
150
- }
151
- });
152
-
153
- // Usage
154
- <Input blockKeys={["c", "r", "f"]} ... />
155
- ```
156
-
157
- ---
158
-
159
- ## 4. Enter Double-Fire
160
-
161
- ### Problem
162
-
163
- After selecting an item in a Select component, the Enter key event propagates
164
- to the next screen and triggers an unwanted action there.
165
-
166
- ### Solution: Ready-state buffering
167
-
168
- ```typescript
169
- const [ready, setReady] = useState(false);
170
-
171
- useEffect(() => {
172
- // Defer input handling until after the first render cycle
173
- const timer = setTimeout(() => setReady(true), 50);
174
- return () => clearTimeout(timer);
175
- }, []);
176
-
177
- useInput((input, key) => {
178
- if (!ready) return; // Drop events during initialization
179
- if (key.return) {
180
- onSelect(selectedItem);
181
- }
182
- });
183
- ```
184
-
185
- ---
186
-
187
- ## 5. CJK / Multi-Width Cursor
188
-
189
- ### Problem
190
-
191
- CJK characters and some symbols display as 2 cells wide but count as 1
192
- character. Calculating cursor position by character count causes drift during
193
- CJK input.
194
-
195
- ### Solution: Display-width based position calculation
196
-
197
- ```typescript
198
- function getCharWidth(char: string): number {
199
- const code = char.codePointAt(0);
200
- if (!code) return 1;
201
-
202
- // CJK, Hangul, emoji ranges render as 2 cells wide
203
- if (
204
- (code >= 0x1100 && code <= 0x115f) || // Hangul Jamo
205
- (code >= 0x2e80 && code <= 0x9fff) || // CJK
206
- (code >= 0xac00 && code <= 0xd7af) || // Hangul Syllables
207
- (code >= 0xf900 && code <= 0xfaff) || // CJK Compatibility
208
- (code >= 0xfe10 && code <= 0xfe1f) || // Vertical forms
209
- (code >= 0x1f300 && code <= 0x1f9ff) // Emojis
210
- ) {
211
- return 2;
212
- }
213
- return 1;
214
- }
215
-
216
- function getDisplayWidth(str: string): number {
217
- return [...str].reduce((width, char) => width + getCharWidth(char), 0);
218
- }
219
-
220
- function toDisplayColumn(text: string, charPosition: number): number {
221
- return getDisplayWidth(text.slice(0, charPosition));
222
- }
223
- ```
224
-
225
- ---
226
-
227
- ## 6. Layout Breaks
228
-
229
- ### Problem
230
-
231
- - Long lines wrap past terminal width
232
- - Timestamps or labels get pushed to the next line
233
- - Column positions drift
234
-
235
- ### Solutions
236
-
237
- **Safe margin**
238
-
239
- ```typescript
240
- const { stdout } = useStdout();
241
- const columns = Math.max(20, (stdout?.columns ?? 80) - 1); // 1-cell margin
242
-
243
- // Or use 90% width (Gemini CLI pattern)
244
- const safeColumns = Math.floor(columns * 0.9);
245
- ```
246
-
247
- **Fixed-width columns**
248
-
249
- ```typescript
250
- const COLUMN_WIDTH = 2;
251
- const padToWidth = (content: string, width: number): string => {
252
- const actualWidth = stringWidth(content);
253
- const padding = Math.max(0, width - actualWidth);
254
- return content + " ".repeat(padding);
255
- };
256
- ```
257
-
258
- **Truncate to width**
259
-
260
- ```typescript
261
- function truncateToWidth(text: string, maxWidth: number): string {
262
- let width = 0;
263
- let result = "";
264
- for (const char of text) {
265
- const charWidth = getCharWidth(char);
266
- if (width + charWidth > maxWidth) {
267
- return result + "…";
268
- }
269
- width += charWidth;
270
- result += char;
271
- }
272
- return result;
273
- }
274
- ```
275
-
276
- ---
277
-
278
- ## 7. console.log Interference
279
-
280
- ### Problem
281
-
282
- `console.log` output competes with Ink's rendering. Ink redraws the screen
283
- periodically, so log lines get overwritten or corrupt the UI.
284
-
285
- ### Solutions
286
-
287
- **Structured logs to stderr**
288
-
289
- ```typescript
290
- import pino from "pino";
291
-
292
- const logger = pino({
293
- transport: {
294
- target: "pino-pretty",
295
- options: { destination: 2 }, // stderr
296
- },
297
- });
298
- ```
299
-
300
- **Conditional debug logging**
301
-
302
- ```typescript
303
- if (process.env.DEBUG) {
304
- console.error("Debug:", data); // stderr, not stdout
305
- }
306
- ```
307
-
308
- ---
309
-
310
- ## 8. Ink Color Type Errors
311
-
312
- ### Problem
313
-
314
- Using `<Text color="cyan">` in TypeScript can trigger strict type errors
315
- because Ink's color types are narrow.
316
-
317
- ### Solutions
318
-
319
- ```typescript
320
- // Use a const assertion
321
- <Text color={"cyan" as const}>...</Text>
322
-
323
- // Or define as a variable
324
- const selectedColor = "cyan" as const;
325
- <Text color={selectedColor}>...</Text>
326
-
327
- // Or use chalk inside the Text node
328
- import chalk from "chalk";
329
- <Text>{chalk.cyan("Selected")}</Text>
330
- ```
@@ -1,384 +0,0 @@
1
- # Testing Patterns & Best Practices
2
-
3
- ## Table of Contents
4
-
5
- 1. [Test Environment Setup](#test-environment-setup)
6
- 2. [Component Tests](#component-tests)
7
- 3. [Mock Patterns](#mock-patterns)
8
- 4. [Integration Tests](#integration-tests)
9
- 5. [Edge Cases](#edge-cases)
10
- 6. [Performance Tests](#performance-tests)
11
- 7. [Test Utilities](#test-utilities)
12
-
13
- ---
14
-
15
- ## Test Environment Setup
16
-
17
- ### Vitest + happy-dom
18
-
19
- ```typescript
20
- /**
21
- * @vitest-environment happy-dom
22
- */
23
- import { describe, it, expect, beforeEach, vi } from "vitest";
24
- import { render } from "@testing-library/react";
25
- import { Window } from "happy-dom";
26
-
27
- describe("Component", () => {
28
- beforeEach(() => {
29
- const window = new Window();
30
- // @ts-expect-error - happy-dom type mismatch
31
- globalThis.window = window;
32
- // @ts-expect-error - happy-dom type mismatch
33
- globalThis.document = window.document;
34
- });
35
- });
36
- ```
37
-
38
- ### ink-testing-library
39
-
40
- ```typescript
41
- import { render } from "ink-testing-library";
42
-
43
- describe("Select", () => {
44
- it("should render items", () => {
45
- const items = [
46
- { label: "Item 1", value: "1" },
47
- { label: "Item 2", value: "2" },
48
- ];
49
-
50
- const { lastFrame } = render(
51
- <Select items={items} onSelect={vi.fn()} />,
52
- );
53
-
54
- expect(lastFrame()).toContain("Item 1");
55
- expect(lastFrame()).toContain("Item 2");
56
- });
57
- });
58
- ```
59
-
60
- ---
61
-
62
- ## Component Tests
63
-
64
- ### Basic Pattern
65
-
66
- ```typescript
67
- import { render } from "ink-testing-library";
68
- import { describe, it, expect, vi } from "vitest";
69
-
70
- describe("Header", () => {
71
- it("should render title", () => {
72
- const { lastFrame } = render(<Header title="Test" />);
73
- expect(lastFrame()).toContain("Test");
74
- });
75
-
76
- it("should render version when provided", () => {
77
- const { lastFrame } = render(
78
- <Header title="Test" version="1.0.0" />,
79
- );
80
- expect(lastFrame()).toContain("1.0.0");
81
- });
82
- });
83
- ```
84
-
85
- ### Key Input Tests
86
-
87
- ```typescript
88
- import { render } from "ink-testing-library";
89
-
90
- describe("Select", () => {
91
- it("should move selection down on j key", async () => {
92
- const items = [
93
- { label: "Item 1", value: "1" },
94
- { label: "Item 2", value: "2" },
95
- ];
96
-
97
- const { stdin, lastFrame } = render(
98
- <Select items={items} onSelect={vi.fn()} />,
99
- );
100
-
101
- // Initial state
102
- expect(lastFrame()).toContain("› Item 1");
103
-
104
- // Press j to move down
105
- stdin.write("j");
106
-
107
- // Selection moved
108
- expect(lastFrame()).toContain("› Item 2");
109
- });
110
-
111
- it("should call onSelect on Enter", () => {
112
- const onSelect = vi.fn();
113
- const items = [{ label: "Item 1", value: "1" }];
114
-
115
- const { stdin } = render(
116
- <Select items={items} onSelect={onSelect} />,
117
- );
118
-
119
- stdin.write("\r"); // Enter key
120
-
121
- expect(onSelect).toHaveBeenCalledWith(items[0]);
122
- });
123
- });
124
- ```
125
-
126
- ### Async Tests
127
-
128
- ```typescript
129
- import { render } from "ink-testing-library";
130
- import { vi } from "vitest";
131
-
132
- describe("LoadingIndicator", () => {
133
- beforeEach(() => {
134
- vi.useFakeTimers();
135
- });
136
-
137
- afterEach(() => {
138
- vi.useRealTimers();
139
- });
140
-
141
- it("should show after delay", async () => {
142
- const { lastFrame } = render(
143
- <LoadingIndicator isLoading={true} delay={300} />,
144
- );
145
-
146
- // Not shown initially
147
- expect(lastFrame()).toBe("");
148
-
149
- // Shown after 300ms
150
- vi.advanceTimersByTime(300);
151
- expect(lastFrame()).toContain("Loading");
152
- });
153
- });
154
- ```
155
-
156
- ---
157
-
158
- ## Mock Patterns
159
-
160
- ### External Dependency Mock
161
-
162
- ```typescript
163
- vi.mock("../../../fs/project.js", () => ({
164
- findProjectRoot: vi.fn().mockResolvedValue("/repo"),
165
- readConfig: vi.fn().mockResolvedValue({ defaultRelease: "v1" }),
166
- getSavepointPath: vi.fn().mockReturnValue("/repo/.savepoint"),
167
- }));
168
- ```
169
-
170
- ### Screen Component Mock
171
-
172
- Mock sibling screens to isolate the component under test:
173
-
174
- ```typescript
175
- const capturedProps: BoardScreenProps[] = [];
176
-
177
- vi.mock("../../components/screens/BoardScreen.js", () => ({
178
- BoardScreen: (props: BoardScreenProps) => {
179
- capturedProps.push(props);
180
- return <div>Mocked BoardScreen</div>;
181
- },
182
- }));
183
-
184
- describe("App", () => {
185
- beforeEach(() => {
186
- capturedProps.length = 0; // Reset
187
- });
188
-
189
- it("should pass tasks to BoardScreen", async () => {
190
- render(<App />);
191
-
192
- await waitFor(() => {
193
- expect(capturedProps.length).toBeGreaterThan(0);
194
- });
195
-
196
- expect(capturedProps[0].tasks).toHaveLength(2);
197
- });
198
- });
199
- ```
200
-
201
- ### Hook Mock
202
-
203
- ```typescript
204
- vi.mock("../../hooks/useAsyncData.js", () => ({
205
- useAsyncData: () => ({
206
- data: [
207
- { id: "T001", title: "Setup project" },
208
- { id: "T002", title: "Add tests" },
209
- ],
210
- loading: false,
211
- error: null,
212
- refresh: vi.fn(),
213
- }),
214
- }));
215
- ```
216
-
217
- ### Conditional Mock Responses
218
-
219
- ```typescript
220
- const mockFetchTasks = vi.fn();
221
-
222
- vi.mock("../../../domain/tasks.js", () => ({
223
- fetchTasks: mockFetchTasks,
224
- }));
225
-
226
- describe("useAsyncData", () => {
227
- it("should handle error", async () => {
228
- mockFetchTasks.mockRejectedValueOnce(new Error("Read error"));
229
- // Assert error state is set
230
- });
231
-
232
- it("should return tasks", async () => {
233
- mockFetchTasks.mockResolvedValueOnce([{ id: "T001" }]);
234
- // Assert data is returned
235
- });
236
- });
237
- ```
238
-
239
- ---
240
-
241
- ## Integration Tests
242
-
243
- ### Navigation Flow
244
-
245
- ```typescript
246
- describe("Navigation", () => {
247
- it("should navigate from board to detail on Enter", async () => {
248
- const { stdin, lastFrame } = render(<App />);
249
-
250
- // Wait for board
251
- await waitFor(() => {
252
- expect(lastFrame()).toContain("Board");
253
- });
254
-
255
- // Press Enter
256
- stdin.write("\r");
257
-
258
- // Detail screen appears
259
- await waitFor(() => {
260
- expect(lastFrame()).toContain("Detail");
261
- });
262
- });
263
-
264
- it("should go back on Escape", async () => {
265
- const { stdin, lastFrame } = render(<App />);
266
-
267
- // Navigate to detail
268
- stdin.write("\r");
269
- await waitFor(() => {
270
- expect(lastFrame()).toContain("Detail");
271
- });
272
-
273
- // Press Escape
274
- stdin.write("\x1B"); // Escape key
275
-
276
- await waitFor(() => {
277
- expect(lastFrame()).toContain("Board");
278
- });
279
- });
280
- });
281
- ```
282
-
283
- ---
284
-
285
- ## Edge Cases
286
-
287
- ```typescript
288
- describe("Edge Cases", () => {
289
- it("should handle empty list", () => {
290
- const { lastFrame } = render(
291
- <Select items={[]} onSelect={vi.fn()} />,
292
- );
293
-
294
- expect(lastFrame()).not.toContain("undefined");
295
- });
296
-
297
- it("should handle very long labels", () => {
298
- const items = [{
299
- label: "A".repeat(200),
300
- value: "1",
301
- }];
302
-
303
- const { lastFrame } = render(
304
- <Select items={items} onSelect={vi.fn()} />,
305
- );
306
-
307
- // Assert output is defined (not crashed)
308
- expect(lastFrame()).toBeDefined();
309
- });
310
- });
311
- ```
312
-
313
- ---
314
-
315
- ## Performance Tests
316
-
317
- ```typescript
318
- describe("Performance", () => {
319
- it("should handle 1000 items without significant lag", async () => {
320
- const items = Array.from({ length: 1000 }, (_, i) => ({
321
- label: `Item ${i}`,
322
- value: String(i),
323
- }));
324
-
325
- const start = performance.now();
326
-
327
- const { stdin } = render(
328
- <Select items={items} onSelect={vi.fn()} limit={20} />,
329
- );
330
-
331
- // 100 navigation keypresses
332
- for (let i = 0; i < 100; i++) {
333
- stdin.write("j");
334
- }
335
-
336
- const duration = performance.now() - start;
337
-
338
- // Must complete within 1 second
339
- expect(duration).toBeLessThan(1000);
340
- });
341
- });
342
- ```
343
-
344
- ---
345
-
346
- ## Test Utilities
347
-
348
- ### waitFor Helper
349
-
350
- ```typescript
351
- async function waitFor(
352
- condition: () => boolean | void,
353
- timeout = 1000,
354
- ): Promise<void> {
355
- const start = Date.now();
356
-
357
- while (Date.now() - start < timeout) {
358
- try {
359
- if (condition()) return;
360
- } catch {
361
- // Condition not yet met
362
- }
363
- await new Promise((r) => setTimeout(r, 10));
364
- }
365
-
366
- throw new Error("waitFor timed out");
367
- }
368
- ```
369
-
370
- ### Key Constants
371
-
372
- ```typescript
373
- const KEYS = {
374
- ENTER: "\r",
375
- ESCAPE: "\x1B",
376
- UP: "\x1B[A",
377
- DOWN: "\x1B[B",
378
- LEFT: "\x1B[D",
379
- RIGHT: "\x1B[C",
380
- TAB: "\t",
381
- BACKSPACE: "\x7F",
382
- CTRL_C: "\x03",
383
- };
384
- ```