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.
- package/package.json +10 -3
- package/{savepoint → savepoint.exe} +0 -0
- package/.claude/settings.local.json +0 -38
- package/.golangci.yml +0 -11
- package/.prettierignore +0 -4
- package/.savepoint/Design.md +0 -206
- package/.savepoint/PRD.md +0 -58
- package/.savepoint/config.yml +0 -27
- package/.savepoint/releases/v1/epics/E01-go-setup/E01-Detail.md +0 -39
- package/.savepoint/releases/v1/epics/E01-go-setup/tasks/T001-init-module.md +0 -42
- package/.savepoint/releases/v1/epics/E01-go-setup/tasks/T002-entrypoint.md +0 -23
- package/.savepoint/releases/v1/epics/E01-go-setup/tasks/T003-directory-structure.md +0 -24
- package/.savepoint/releases/v1/epics/E01-go-setup/tasks/T004-makefile.md +0 -23
- package/.savepoint/releases/v1/epics/E02-data-readers/E02-Detail.md +0 -61
- package/.savepoint/releases/v1/epics/E02-data-readers/tasks/T001-task-struct.md +0 -29
- package/.savepoint/releases/v1/epics/E02-data-readers/tasks/T002-frontmatter-parser.md +0 -30
- package/.savepoint/releases/v1/epics/E02-data-readers/tasks/T003-router-reader.md +0 -29
- package/.savepoint/releases/v1/epics/E02-data-readers/tasks/T004-config-reader.md +0 -29
- package/.savepoint/releases/v1/epics/E02-data-readers/tasks/T005-discovery.md +0 -30
- package/.savepoint/releases/v1/epics/E03-board-tui-core/E03-Detail.md +0 -38
- package/.savepoint/releases/v1/epics/E03-board-tui-core/tasks/T001-model.md +0 -29
- package/.savepoint/releases/v1/epics/E03-board-tui-core/tasks/T002-update-loop.md +0 -30
- package/.savepoint/releases/v1/epics/E03-board-tui-core/tasks/T003-view.md +0 -34
- package/.savepoint/releases/v1/epics/E03-board-tui-core/tasks/T004-styles.md +0 -29
- package/.savepoint/releases/v1/epics/E03-board-tui-core/tasks/T005-layout.md +0 -42
- package/.savepoint/releases/v1/epics/E04-board-components/E04-Detail.md +0 -44
- package/.savepoint/releases/v1/epics/E04-board-components/tasks/T001-column.md +0 -34
- package/.savepoint/releases/v1/epics/E04-board-components/tasks/T002-card.md +0 -33
- package/.savepoint/releases/v1/epics/E04-board-components/tasks/T003-epic-panel.md +0 -49
- package/.savepoint/releases/v1/epics/E04-board-components/tasks/T004-detail-overlay.md +0 -40
- package/.savepoint/releases/v1/epics/E04-board-components/tasks/T005-release-dropdown.md +0 -33
- package/.savepoint/releases/v1/epics/E04-board-components/tasks/T006-help-overlay.md +0 -34
- package/.savepoint/releases/v1/epics/E05-phase-transitions/E05-Detail.md +0 -38
- package/.savepoint/releases/v1/epics/E05-phase-transitions/tasks/T001-phase-stepping.md +0 -29
- package/.savepoint/releases/v1/epics/E05-phase-transitions/tasks/T002-gates.md +0 -31
- package/.savepoint/releases/v1/epics/E05-phase-transitions/tasks/T003-write-task.md +0 -31
- package/.savepoint/releases/v1/epics/E05-phase-transitions/tasks/T004-write-router.md +0 -31
- package/.savepoint/releases/v1/epics/E06-atari-noir-layout/E06-Detail.md +0 -62
- package/.savepoint/releases/v1/epics/E06-atari-noir-layout/tasks/T001-color-system.md +0 -39
- package/.savepoint/releases/v1/epics/E06-atari-noir-layout/tasks/T002-header-and-dividers.md +0 -52
- package/.savepoint/releases/v1/epics/E06-atari-noir-layout/tasks/T003-footer-status-bar.md +0 -52
- package/.savepoint/releases/v1/epics/E06-atari-noir-layout/tasks/T004-component-refinement.md +0 -53
- package/.savepoint/releases/v1/epics/E06-atari-noir-layout/tasks/T005-restore-nav-hints.md +0 -39
- package/.savepoint/releases/v1/epics/E06-atari-noir-layout/tasks/T007-detail-card-fixes.md +0 -36
- package/.savepoint/releases/v1/epics/E06-atari-noir-layout/tasks/T008-checkbox-states.md +0 -40
- package/.savepoint/releases/v1/epics/E06-atari-noir-layout/tasks/T009-router-priority-marker.md +0 -48
- package/.savepoint/releases/v1/epics/E06-atari-noir-layout/tasks/T010-auto-refresh-watcher.md +0 -66
- package/.savepoint/releases/v1/epics/_archived/E01-archive-and-reset/Design.md +0 -39
- package/.savepoint/releases/v1/epics/_archived/E01-archive-and-reset/tasks/T001-archive-epics.md +0 -20
- package/.savepoint/releases/v1/epics/_archived/E01-archive-and-reset/tasks/T002-rewrite-prd.md +0 -22
- package/.savepoint/releases/v1/epics/_archived/E01-archive-and-reset/tasks/T003-create-epic-stubs.md +0 -24
- package/.savepoint/releases/v1/epics/_archived/E01-archive-and-reset/tasks/T004-update-router.md +0 -22
- package/.savepoint/releases/v1/epics/_archived/E01-scaffolding/Design.md +0 -118
- package/.savepoint/releases/v1/epics/_archived/E01-scaffolding/handoff.md +0 -9
- package/.savepoint/releases/v1/epics/_archived/E01-scaffolding/tasks/T001-package-baseline.md +0 -45
- package/.savepoint/releases/v1/epics/_archived/E01-scaffolding/tasks/T002-typescript-build.md +0 -48
- package/.savepoint/releases/v1/epics/_archived/E01-scaffolding/tasks/T003-vitest-smoke.md +0 -43
- package/.savepoint/releases/v1/epics/_archived/E01-scaffolding/tasks/T004-lint-format-gates.md +0 -45
- package/.savepoint/releases/v1/epics/_archived/E01-scaffolding/tasks/T005-scaffold-verification.md +0 -40
- package/.savepoint/releases/v1/epics/_archived/E02-data-model/Design.md +0 -142
- package/.savepoint/releases/v1/epics/_archived/E02-data-model/tasks/T001-domain-ids-status.md +0 -27
- package/.savepoint/releases/v1/epics/_archived/E02-data-model/tasks/T002-markdown-frontmatter-boundary.md +0 -28
- package/.savepoint/releases/v1/epics/_archived/E02-data-model/tasks/T003-task-documents.md +0 -29
- package/.savepoint/releases/v1/epics/_archived/E02-data-model/tasks/T004-release-epic-router-config-readers.md +0 -30
- package/.savepoint/releases/v1/epics/_archived/E02-data-model/tasks/T005-dependency-validation.md +0 -29
- package/.savepoint/releases/v1/epics/_archived/E02-data-model/tasks/T006-epic-task-set-reader.md +0 -29
- package/.savepoint/releases/v1/epics/_archived/E02-data-model/tasks/T007-quality-gates.md +0 -31
- package/.savepoint/releases/v1/epics/_archived/E02-domain-phase-model/Design.md +0 -40
- package/.savepoint/releases/v1/epics/_archived/E02-domain-phase-model/tasks/T001-phase-types.md +0 -27
- package/.savepoint/releases/v1/epics/_archived/E02-domain-phase-model/tasks/T002-phase-frontmatter.md +0 -25
- package/.savepoint/releases/v1/epics/_archived/E02-domain-phase-model/tasks/T003-simplify-config.md +0 -26
- package/.savepoint/releases/v1/epics/_archived/E02-domain-phase-model/tasks/T004-simplify-router-domain.md +0 -24
- package/.savepoint/releases/v1/epics/_archived/E03-cli-foundation/Design.md +0 -122
- package/.savepoint/releases/v1/epics/_archived/E03-cli-foundation/tasks/T001-argument-parser-contract.md +0 -28
- package/.savepoint/releases/v1/epics/_archived/E03-cli-foundation/tasks/T002-help-text-generation.md +0 -28
- package/.savepoint/releases/v1/epics/_archived/E03-cli-foundation/tasks/T003-terminal-environment-detection.md +0 -27
- package/.savepoint/releases/v1/epics/_archived/E03-cli-foundation/tasks/T004-command-stub-modules.md +0 -29
- package/.savepoint/releases/v1/epics/_archived/E03-cli-foundation/tasks/T005-cli-runner-dispatch.md +0 -34
- package/.savepoint/releases/v1/epics/_archived/E03-cli-foundation/tasks/T006-entrypoint-quality-gates.md +0 -32
- package/.savepoint/releases/v1/epics/_archived/E03-cli-simplify/Design.md +0 -43
- package/.savepoint/releases/v1/epics/_archived/E03-cli-simplify/tasks/T001-strip-args.md +0 -26
- package/.savepoint/releases/v1/epics/_archived/E03-cli-simplify/tasks/T002-strip-help.md +0 -23
- package/.savepoint/releases/v1/epics/_archived/E03-cli-simplify/tasks/T003-strip-run.md +0 -23
- package/.savepoint/releases/v1/epics/_archived/E03-cli-simplify/tasks/T004-delete-commands.md +0 -24
- package/.savepoint/releases/v1/epics/_archived/E03-cli-simplify/tasks/T005-update-cli-tests.md +0 -22
- package/.savepoint/releases/v1/epics/_archived/E04-board-phase-integration/Design.md +0 -48
- package/.savepoint/releases/v1/epics/_archived/E04-board-phase-integration/tasks/T001-board-data-phases.md +0 -26
- package/.savepoint/releases/v1/epics/_archived/E04-board-phase-integration/tasks/T002-phase-rendering.md +0 -28
- package/.savepoint/releases/v1/epics/_archived/E04-board-phase-integration/tasks/T003-detail-pane-phases.md +0 -27
- package/.savepoint/releases/v1/epics/_archived/E04-board-phase-integration/tasks/T004-phase-transitions.md +0 -42
- package/.savepoint/releases/v1/epics/_archived/E04-board-phase-integration/tasks/T005-phase-gates.md +0 -24
- package/.savepoint/releases/v1/epics/_archived/E04-board-phase-integration/tasks/T006-phase-write-back.md +0 -24
- package/.savepoint/releases/v1/epics/_archived/E04-board-phase-integration/tasks/T007-remove-audit-flow.md +0 -27
- package/.savepoint/releases/v1/epics/_archived/E04-board-phase-integration/tasks/T008-board-tests.md +0 -25
- package/.savepoint/releases/v1/epics/_archived/E04-templates-and-prompts/Design.md +0 -85
- package/.savepoint/releases/v1/epics/_archived/E04-templates-and-prompts/tasks/T001-project-template-assets.md +0 -17
- package/.savepoint/releases/v1/epics/_archived/E04-templates-and-prompts/tasks/T002-release-and-prompt-assets.md +0 -20
- package/.savepoint/releases/v1/epics/_archived/E04-templates-and-prompts/tasks/T003-template-registry-renderer.md +0 -22
- package/.savepoint/releases/v1/epics/_archived/E04-templates-and-prompts/tasks/T004-template-integrity-tests.md +0 -17
- package/.savepoint/releases/v1/epics/_archived/E04-templates-and-prompts/tasks/T005-template-closeout-quality-gates.md +0 -16
- package/.savepoint/releases/v1/epics/_archived/E05-init-command/Design.md +0 -88
- package/.savepoint/releases/v1/epics/_archived/E05-init-command/tasks/T001-init-cli-contract.md +0 -22
- package/.savepoint/releases/v1/epics/_archived/E05-init-command/tasks/T002-target-validation.md +0 -23
- package/.savepoint/releases/v1/epics/_archived/E05-init-command/tasks/T003-scaffold-writer.md +0 -24
- package/.savepoint/releases/v1/epics/_archived/E05-init-command/tasks/T004-magic-prompt-and-clipboard.md +0 -23
- package/.savepoint/releases/v1/epics/_archived/E05-init-command/tasks/T005-dev-deps-install-option.md +0 -24
- package/.savepoint/releases/v1/epics/_archived/E05-init-command/tasks/T006-init-command-integration.md +0 -28
- package/.savepoint/releases/v1/epics/_archived/E05-project-cleanup/Design.md +0 -53
- package/.savepoint/releases/v1/epics/_archived/E05-project-cleanup/tasks/T001-delete-dead-src.md +0 -23
- package/.savepoint/releases/v1/epics/_archived/E05-project-cleanup/tasks/T002-delete-dead-tests.md +0 -26
- package/.savepoint/releases/v1/epics/_archived/E05-project-cleanup/tasks/T003-delete-assets.md +0 -25
- package/.savepoint/releases/v1/epics/_archived/E05-project-cleanup/tasks/T004-clean-savepoint.md +0 -28
- package/.savepoint/releases/v1/epics/_archived/E05-project-cleanup/tasks/T005-rewrite-agents-md.md +0 -28
- package/.savepoint/releases/v1/epics/_archived/E05-project-cleanup/tasks/T006-clean-package-json.md +0 -23
- package/.savepoint/releases/v1/epics/_archived/E05-project-cleanup/tasks/T007-verify.md +0 -25
- package/.savepoint/releases/v1/epics/_archived/E06-tui-board/Design.md +0 -104
- package/.savepoint/releases/v1/epics/_archived/E06-tui-board/tasks/T001-board-command-data.md +0 -23
- package/.savepoint/releases/v1/epics/_archived/E06-tui-board/tasks/T002-board-view-state.md +0 -24
- package/.savepoint/releases/v1/epics/_archived/E06-tui-board/tasks/T003-transition-gates-and-writes.md +0 -25
- package/.savepoint/releases/v1/epics/_archived/E06-tui-board/tasks/T004-terminal-theme.md +0 -23
- package/.savepoint/releases/v1/epics/_archived/E06-tui-board/tasks/T005-ink-board-ui.md +0 -26
- package/.savepoint/releases/v1/epics/_archived/E06-tui-board/tasks/T006-board-integration-audit-entry.md +0 -24
- package/.savepoint/releases/v1/epics/_archived/E07-audit-pipeline/Design.md +0 -88
- package/.savepoint/releases/v1/epics/_archived/E07-audit-pipeline/tasks/T001-audit-cli-contract.md +0 -23
- package/.savepoint/releases/v1/epics/_archived/E07-audit-pipeline/tasks/T002-quality-gate-runner.md +0 -23
- package/.savepoint/releases/v1/epics/_archived/E07-audit-pipeline/tasks/T003-snapshot-and-prompt.md +0 -23
- package/.savepoint/releases/v1/epics/_archived/E07-audit-pipeline/tasks/T004-audit-orchestration-router.md +0 -27
- package/.savepoint/releases/v1/epics/_archived/E07-audit-pipeline/tasks/T005-proposal-validation-apply.md +0 -25
- package/.savepoint/releases/v1/epics/_archived/E07-audit-pipeline/tasks/T006-audit-review-state.md +0 -24
- package/.savepoint/releases/v1/epics/_archived/E07-audit-pipeline/tasks/T007-audit-review-ui.md +0 -26
- package/.savepoint/releases/v1/epics/_archived/E07-audit-pipeline/tasks/T008-audit-pipeline-integration.md +0 -24
- package/.savepoint/releases/v1/epics/_archived/E08-board-workflow-cleanup/Design.md +0 -103
- package/.savepoint/releases/v1/epics/_archived/E08-board-workflow-cleanup/tasks/T001-acceptance-criteria-model.md +0 -30
- package/.savepoint/releases/v1/epics/_archived/E08-board-workflow-cleanup/tasks/T002-release-task-set-reader.md +0 -33
- package/.savepoint/releases/v1/epics/_archived/E08-board-workflow-cleanup/tasks/T003-board-data-and-plain-output.md +0 -34
- package/.savepoint/releases/v1/epics/_archived/E08-board-workflow-cleanup/tasks/T004-board-selection-state.md +0 -33
- package/.savepoint/releases/v1/epics/_archived/E08-board-workflow-cleanup/tasks/T005-ink-board-layout-cleanup.md +0 -37
- package/.savepoint/releases/v1/epics/_archived/E08-board-workflow-cleanup/tasks/T006-task-detail-popup.md +0 -36
- package/.savepoint/releases/v1/epics/_archived/E08-board-workflow-cleanup/tasks/T007-templates-acceptance-criteria.md +0 -34
- package/.savepoint/releases/v1/epics/_archived/E08-board-workflow-cleanup/tasks/T008-board-workflow-integration.md +0 -41
- package/.savepoint/releases/v1/epics/_archived/E09-doctor-command/Design.md +0 -70
- package/.savepoint/releases/v1/epics/_archived/E10-docs-and-packaging/Design.md +0 -68
- package/.savepoint/releases/v1/epics/_archived/E11-release-validation/Design.md +0 -68
- package/.savepoint/releases/v1/v1-PRD.md +0 -66
- package/.savepoint/releases/v1.1/epics/E01-tui-optimisation/E01-Detail.md +0 -40
- package/.savepoint/releases/v1.1/epics/E01-tui-optimisation/tasks/T001-next-activity-header.md +0 -56
- package/.savepoint/releases/v1.1/epics/E01-tui-optimisation/tasks/T002-rename-epic-design-files.md +0 -38
- package/.savepoint/releases/v1.1/epics/E01-tui-optimisation/tasks/T003-rename-release-prd.md +0 -28
- package/.savepoint/releases/v1.1/epics/E01-tui-optimisation/tasks/T004-update-instruction-files.md +0 -51
- package/.savepoint/releases/v1.1/epics/E01-tui-optimisation/tasks/T005-update-cross-references.md +0 -45
- package/.savepoint/releases/v1.1/epics/E01-tui-optimisation/tasks/T006-column-and-detail-scrolling.md +0 -68
- package/.savepoint/releases/v1.1/epics/E01-tui-optimisation/tasks/T007-column-focus-border-stability.md +0 -57
- package/.savepoint/releases/v1.1/epics/E02-cross-platform-compatibility/E02-Audit.md +0 -124
- package/.savepoint/releases/v1.1/epics/E02-cross-platform-compatibility/E02-Detail.md +0 -49
- package/.savepoint/releases/v1.1/epics/E02-cross-platform-compatibility/tasks/T001-fix-makefile.md +0 -37
- package/.savepoint/releases/v1.1/epics/E02-cross-platform-compatibility/tasks/T002-linux-build-target.md +0 -38
- package/.savepoint/releases/v1.1/epics/E02-cross-platform-compatibility/tasks/T003-macos-build-target.md +0 -36
- package/.savepoint/releases/v1.1/epics/E02-cross-platform-compatibility/tasks/T004-smoke-tests-and-artifacts.md +0 -59
- package/.savepoint/releases/v1.1/epics/E03-ui-visual-refinement/E03-Audit.md +0 -195
- package/.savepoint/releases/v1.1/epics/E03-ui-visual-refinement/E03-Detail.md +0 -45
- package/.savepoint/releases/v1.1/epics/E03-ui-visual-refinement/tasks/T001-border-resize-fix.md +0 -40
- package/.savepoint/releases/v1.1/epics/E03-ui-visual-refinement/tasks/T002-next-activity-below-header.md +0 -64
- package/.savepoint/releases/v1.1/epics/E03-ui-visual-refinement/tasks/T003-checkbox-rendering-fix.md +0 -56
- package/.savepoint/releases/v1.1/epics/E03-ui-visual-refinement/tasks/T005-unify-status-glyphs.md +0 -65
- package/.savepoint/releases/v1.1/epics/E03-ui-visual-refinement/tasks/T006-forced-256-color-profile.md +0 -36
- package/.savepoint/releases/v1.1/epics/E04-epic-navigation/E04-Audit.md +0 -167
- package/.savepoint/releases/v1.1/epics/E04-epic-navigation/E04-Detail.md +0 -51
- package/.savepoint/releases/v1.1/epics/E04-epic-navigation/tasks/T001-sidebar-focusable-navigation.md +0 -65
- package/.savepoint/releases/v1.1/epics/E04-epic-navigation/tasks/T002-epic-detail-overlay.md +0 -73
- package/.savepoint/releases/v1.1/epics/E04-epic-navigation/tasks/T003-epic-status-glyphs.md +0 -73
- package/.savepoint/releases/v1.1/epics/E05-tasking-permissions/E05-Audit.md +0 -237
- package/.savepoint/releases/v1.1/epics/E05-tasking-permissions/E05-Detail.md +0 -54
- package/.savepoint/releases/v1.1/epics/E05-tasking-permissions/tasks/T001-update-agents-md.md +0 -45
- package/.savepoint/releases/v1.1/epics/E05-tasking-permissions/tasks/T002-update-router-md.md +0 -40
- package/.savepoint/releases/v1.1/epics/E05-tasking-permissions/tasks/T003-update-design-md.md +0 -47
- package/.savepoint/releases/v1.1/epics/E05-tasking-permissions/tasks/T004-implement-m-hotkey.md +0 -98
- package/.savepoint/releases/v1.1/epics/E05-tasking-permissions/tasks/T005-update-help-overlay.md +0 -33
- package/.savepoint/releases/v1.1/epics/E05-tasking-permissions/tasks/T006-tests-and-quality-gates.md +0 -62
- package/.savepoint/releases/v1.1/epics/E06-audit-command/E06-Audit.md +0 -56
- package/.savepoint/releases/v1.1/epics/E06-audit-command/E06-Detail.md +0 -63
- package/.savepoint/releases/v1.1/epics/E06-audit-command/tasks/T005-proposals.md +0 -44
- package/.savepoint/releases/v1.1/epics/E06-audit-command/tasks/T007-apply-close.md +0 -35
- package/.savepoint/releases/v1.1/epics/E06-audit-command/tasks/T009-integration.md +0 -40
- package/.savepoint/releases/v1.1/epics/E06-audit-command/tasks/T010-audit-file-migration.md +0 -45
- package/.savepoint/releases/v1.1/epics/E06-audit-command/tasks/T011-model-tab-state.md +0 -26
- package/.savepoint/releases/v1.1/epics/E06-audit-command/tasks/T012-epic-audit-render.md +0 -33
- package/.savepoint/releases/v1.1/epics/E06-audit-command/tasks/T013-handle-tab-keys.md +0 -34
- package/.savepoint/releases/v1.1/epics/E06-audit-command/tasks/T014-tab-indicator.md +0 -33
- package/.savepoint/releases/v1.1/epics/E07-init-command/E07-Audit.md +0 -336
- package/.savepoint/releases/v1.1/epics/E07-init-command/E07-Detail.md +0 -61
- package/.savepoint/releases/v1.1/epics/E07-init-command/tasks/T001-cli-entrypoint.md +0 -37
- package/.savepoint/releases/v1.1/epics/E07-init-command/tasks/T002-target-validation.md +0 -28
- package/.savepoint/releases/v1.1/epics/E07-init-command/tasks/T003-scaffold-writer.md +0 -46
- package/.savepoint/releases/v1.1/epics/E07-init-command/tasks/T004-atomic-writes.md +0 -27
- package/.savepoint/releases/v1.1/epics/E07-init-command/tasks/T005-magic-prompt.md +0 -25
- package/.savepoint/releases/v1.1/epics/E07-init-command/tasks/T006-clipboard.md +0 -26
- package/.savepoint/releases/v1.1/epics/E07-init-command/tasks/T007-integration-test.md +0 -26
- package/.savepoint/releases/v1.1/epics/E08-board-command/E08-Audit.md +0 -333
- package/.savepoint/releases/v1.1/epics/E08-board-command/E08-Detail.md +0 -68
- package/.savepoint/releases/v1.1/epics/E08-board-command/tasks/T001-cli-entrypoint.md +0 -26
- package/.savepoint/releases/v1.1/epics/E08-board-command/tasks/T002-non-tty-fallback.md +0 -27
- package/.savepoint/releases/v1.1/epics/E08-board-command/tasks/T003-tui-app-shell.md +0 -28
- package/.savepoint/releases/v1.1/epics/E08-board-command/tasks/T004-board-model.md +0 -29
- package/.savepoint/releases/v1.1/epics/E08-board-command/tasks/T005-detail-pane.md +0 -27
- package/.savepoint/releases/v1.1/epics/E08-board-command/tasks/T006-status-transitions.md +0 -29
- package/.savepoint/releases/v1.1/epics/E08-board-command/tasks/T007-theme-fallbacks.md +0 -29
- package/.savepoint/releases/v1.1/epics/E08-board-command/tasks/T008-integration-test.md +0 -27
- package/.savepoint/releases/v1.1/epics/E09-doctor-command/E09-Audit.md +0 -207
- package/.savepoint/releases/v1.1/epics/E09-doctor-command/E09-Detail.md +0 -65
- package/.savepoint/releases/v1.1/epics/E09-doctor-command/tasks/T001-cli-entrypoint.md +0 -24
- package/.savepoint/releases/v1.1/epics/E09-doctor-command/tasks/T002-config-router-validation.md +0 -28
- package/.savepoint/releases/v1.1/epics/E09-doctor-command/tasks/T003-structure-checks.md +0 -29
- package/.savepoint/releases/v1.1/epics/E09-doctor-command/tasks/T004-dependency-checks.md +0 -27
- package/.savepoint/releases/v1.1/epics/E09-doctor-command/tasks/T005-audit-orphan-checks.md +0 -28
- package/.savepoint/releases/v1.1/epics/E09-doctor-command/tasks/T006-quality-gates-report.md +0 -31
- package/.savepoint/releases/v1.1/epics/E11-board-refresh-fix/E11-Detail.md +0 -36
- package/.savepoint/releases/v1.1/epics/E11-board-refresh-fix/tasks/T001-debug-logging.md +0 -25
- package/.savepoint/releases/v1.1/epics/E11-board-refresh-fix/tasks/T002-increase-debounce.md +0 -21
- package/.savepoint/releases/v1.1/epics/E11-board-refresh-fix/tasks/T003-error-handling.md +0 -22
- package/.savepoint/releases/v1.1/epics/E11-board-refresh-fix/tasks/T004-test-verify.md +0 -29
- package/.savepoint/releases/v1.1/epics/E12-validation-fix/E12-Audit.md +0 -444
- package/.savepoint/releases/v1.1/epics/E12-validation-fix/E12-Detail.md +0 -45
- package/.savepoint/releases/v1.1/epics/E12-validation-fix/tasks/T001-default-phase.md +0 -35
- package/.savepoint/releases/v1.1/epics/E12-validation-fix/tasks/T002-default-status.md +0 -19
- package/.savepoint/releases/v1.1/epics/E12-validation-fix/tasks/T003-better-errors.md +0 -29
- package/.savepoint/releases/v1.1/epics/E12-validation-fix/tasks/T004-validate-on-write.md +0 -25
- package/.savepoint/releases/v1.1/epics/E12-validation-fix/tasks/T005-tests.md +0 -37
- package/.savepoint/releases/v1.1/epics/E13-audit-remediation/E13-Audit.md +0 -118
- package/.savepoint/releases/v1.1/epics/E13-audit-remediation/E13-Detail.md +0 -73
- package/.savepoint/releases/v1.1/epics/E13-audit-remediation/tasks/T001-safe-cleanup.md +0 -66
- package/.savepoint/releases/v1.1/epics/E13-audit-remediation/tasks/T002-bug-fixes.md +0 -35
- package/.savepoint/releases/v1.1/epics/E13-audit-remediation/tasks/T003-centralize-duplication.md +0 -60
- package/.savepoint/releases/v1.1/epics/E13-audit-remediation/tasks/T004-infrastructure.md +0 -33
- package/.savepoint/releases/v1.1/epics/E13-audit-remediation/tasks/T005-decompose-update.md +0 -37
- package/.savepoint/releases/v1.1/epics/E13-audit-remediation/tasks/T006-async-io.md +0 -40
- package/.savepoint/releases/v1.1/epics/E13-audit-remediation/tasks/T007-test-coverage.md +0 -37
- package/.savepoint/releases/v1.1/epics/E14-structural-improvements/E14-Audit.md +0 -267
- package/.savepoint/releases/v1.1/epics/E14-structural-improvements/E14-Detail.md +0 -54
- package/.savepoint/releases/v1.1/epics/E14-structural-improvements/tasks/T001-group-model.md +0 -39
- package/.savepoint/releases/v1.1/epics/E14-structural-improvements/tasks/T002-data-interfaces.md +0 -42
- package/.savepoint/releases/v1.1/epics/E14-structural-improvements/tasks/T003-discover-orphans.md +0 -33
- package/.savepoint/releases/v1.1/epics/E14-structural-improvements/tasks/T004-epic-panel-headings.md +0 -35
- package/.savepoint/releases/v1.1/epics/E14-structural-improvements/tasks/T005-shell-tokenization.md +0 -27
- package/.savepoint/releases/v1.1/epics/E14-structural-improvements/tasks/T006-unify-enums.md +0 -29
- package/.savepoint/releases/v1.1/epics/E14-structural-improvements/tasks/T007-testutil-package.md +0 -28
- package/.savepoint/releases/v1.1/epics/E15-hardening/E15-Detail.md +0 -43
- package/.savepoint/releases/v1.1/epics/E15-hardening/tasks/T001-benchmarks.md +0 -31
- package/.savepoint/releases/v1.1/epics/E15-hardening/tasks/T002-fuzz-targets.md +0 -28
- package/.savepoint/releases/v1.1/epics/E15-hardening/tasks/T003-debug-flag.md +0 -30
- package/.savepoint/releases/v1.1/epics/E15-hardening/tasks/T004-dist-checksums.md +0 -27
- package/.savepoint/releases/v1.1/epics/E15-hardening/tasks/T005-windows-targets.md +0 -28
- package/.savepoint/releases/v1.1/epics/E15-hardening/tasks/T006-abbreviation-splitting.md +0 -26
- package/.savepoint/releases/v1.1/epics/E15-hardening/tasks/T007-root-test-allowlist.md +0 -28
- package/.savepoint/releases/v1.1/epics/_archived/T001-cli-entrypoint.md +0 -25
- package/.savepoint/releases/v1.1/epics/_archived/T002-quality-gates.md +0 -27
- package/.savepoint/releases/v1.1/epics/_archived/T003-snapshot.md +0 -27
- package/.savepoint/releases/v1.1/epics/_archived/T004-ai-reconcile.md +0 -29
- package/.savepoint/releases/v1.1/epics/_archived/T006-tui-review.md +0 -31
- package/.savepoint/releases/v1.1/epics/_archived/T008-skip-handling.md +0 -34
- package/.savepoint/releases/v1.1/v1.1-PRD.md +0 -139
- package/.savepoint/router.md +0 -57
- package/.savepoint/visual-identity.md +0 -125
- package/AGENTS.md +0 -99
- package/CLAUDE.md +0 -1
- package/GEMINI.md +0 -1
- package/Makefile +0 -29
- package/agent-skills/ink-tui-design/SKILL.md +0 -309
- package/agent-skills/ink-tui-design/references/component-patterns.md +0 -371
- package/agent-skills/ink-tui-design/references/hooks-guide.md +0 -436
- package/agent-skills/ink-tui-design/references/ink-gotchas.md +0 -330
- package/agent-skills/ink-tui-design/references/testing-patterns.md +0 -384
- package/agent-skills/savepoint-audit/SKILL.md +0 -87
- package/agent-skills/savepoint-build-task/SKILL.md +0 -44
- package/agent-skills/savepoint-create-plan/SKILL.md +0 -33
- package/agent-skills/savepoint-create-task/SKILL.md +0 -44
- package/agent-skills/savepoint-draft-prd/SKILL.md +0 -37
- package/agent-skills/savepoint-system-design/SKILL.md +0 -38
- package/agent-skills/superpowers/brainstorming/SKILL.md +0 -165
- package/agent-skills/superpowers/brainstorming/visual-companion.md +0 -304
- package/agent-skills/superpowers/dispatching-parallel-agents/SKILL.md +0 -193
- package/agent-skills/superpowers/executing-plans/SKILL.md +0 -77
- package/agent-skills/superpowers/finishing-a-development-branch/SKILL.md +0 -213
- package/agent-skills/superpowers/receiving-code-review/SKILL.md +0 -226
- package/agent-skills/superpowers/requesting-code-review/SKILL.md +0 -115
- package/agent-skills/superpowers/requesting-code-review/code-reviewer.md +0 -160
- package/agent-skills/superpowers/subagent-driven-development/SKILL.md +0 -292
- package/agent-skills/superpowers/subagent-driven-development/code-quality-reviewer-prompt.md +0 -27
- package/agent-skills/superpowers/subagent-driven-development/implementer-prompt.md +0 -113
- package/agent-skills/superpowers/subagent-driven-development/spec-reviewer-prompt.md +0 -61
- package/agent-skills/superpowers/systematic-debugging/SKILL.md +0 -305
- package/agent-skills/superpowers/systematic-debugging/condition-based-waiting.md +0 -122
- package/agent-skills/superpowers/systematic-debugging/defense-in-depth.md +0 -130
- package/agent-skills/superpowers/systematic-debugging/root-cause-tracing.md +0 -183
- package/agent-skills/superpowers/test-driven-development/SKILL.md +0 -389
- package/agent-skills/superpowers/test-driven-development/testing-anti-patterns.md +0 -317
- package/agent-skills/superpowers/verification-before-completion/SKILL.md +0 -147
- package/agent-skills/superpowers/writing-plans/SKILL.md +0 -159
- package/agent-skills/superpowers/writing-plans/plan-document-reviewer-prompt.md +0 -49
- package/agent_skills_test.go +0 -91
- package/assets/banner.png +0 -0
- package/assets/logo.png +0 -0
- package/assets/strawman.png +0 -0
- package/cmd/board.go +0 -59
- package/cmd/board_test.go +0 -137
- package/cmd/doctor.go +0 -53
- package/cmd/doctor_test.go +0 -146
- package/cmd/init.go +0 -63
- package/cmd/init_test.go +0 -104
- package/go.mod +0 -36
- package/go.sum +0 -75
- package/internal/board/board.go +0 -177
- package/internal/board/board_test.go +0 -168
- package/internal/board/card.go +0 -129
- package/internal/board/card_test.go +0 -254
- package/internal/board/column.go +0 -127
- package/internal/board/column_test.go +0 -139
- package/internal/board/detail.go +0 -185
- package/internal/board/detail_test.go +0 -340
- package/internal/board/epic_panel.go +0 -262
- package/internal/board/epic_panel_test.go +0 -869
- package/internal/board/help.go +0 -41
- package/internal/board/help_test.go +0 -86
- package/internal/board/integration_test.go +0 -266
- package/internal/board/interfaces.go +0 -65
- package/internal/board/interfaces_test.go +0 -114
- package/internal/board/io.go +0 -93
- package/internal/board/layout.go +0 -68
- package/internal/board/layout_test.go +0 -106
- package/internal/board/model.go +0 -235
- package/internal/board/model_test.go +0 -67
- package/internal/board/plain.go +0 -88
- package/internal/board/plain_test.go +0 -117
- package/internal/board/release.go +0 -34
- package/internal/board/release_test.go +0 -177
- package/internal/board/render_policy_test.go +0 -77
- package/internal/board/status.go +0 -23
- package/internal/board/theme.go +0 -24
- package/internal/board/theme_test.go +0 -31
- package/internal/board/transitions.go +0 -113
- package/internal/board/transitions_test.go +0 -164
- package/internal/board/tui.go +0 -32
- package/internal/board/update.go +0 -556
- package/internal/board/update_test.go +0 -575
- package/internal/board/util.go +0 -76
- package/internal/board/view.go +0 -317
- package/internal/board/view_test.go +0 -315
- package/internal/board/watch.go +0 -130
- package/internal/buildtool/main.go +0 -211
- package/internal/buildtool/main_test.go +0 -46
- package/internal/data/config.go +0 -101
- package/internal/data/config_test.go +0 -122
- package/internal/data/discover.go +0 -178
- package/internal/data/discover_test.go +0 -130
- package/internal/data/errors.go +0 -13
- package/internal/data/lifecycle.go +0 -44
- package/internal/data/lifecycle_test.go +0 -41
- package/internal/data/parser.go +0 -242
- package/internal/data/parser_test.go +0 -281
- package/internal/data/router.go +0 -52
- package/internal/data/router_test.go +0 -35
- package/internal/data/task.go +0 -57
- package/internal/data/task_test.go +0 -51
- package/internal/data/write.go +0 -218
- package/internal/data/write_test.go +0 -623
- package/internal/doctor/checks.go +0 -567
- package/internal/doctor/checks_test.go +0 -716
- package/internal/doctor/gates.go +0 -193
- package/internal/doctor/gates_test.go +0 -166
- package/internal/doctor/interfaces.go +0 -64
- package/internal/doctor/interfaces_test.go +0 -104
- package/internal/doctor/repairs.go +0 -80
- package/internal/doctor/repairs_test.go +0 -81
- package/internal/doctor/report.go +0 -157
- package/internal/doctor/report_test.go +0 -89
- package/internal/init/clipboard.go +0 -146
- package/internal/init/clipboard_test.go +0 -74
- package/internal/init/install.go +0 -16
- package/internal/init/integration_test.go +0 -197
- package/internal/init/prompt.go +0 -14
- package/internal/init/prompt_test.go +0 -77
- package/internal/init/scaffold.go +0 -59
- package/internal/init/scaffold_test.go +0 -179
- package/internal/init/template_freshness_test.go +0 -56
- package/internal/init/validate.go +0 -85
- package/internal/init/validate_test.go +0 -141
- package/internal/init/write.go +0 -73
- package/internal/init/write_test.go +0 -91
- package/internal/styles/palette.go +0 -49
- package/internal/styles/styles.go +0 -139
- package/internal/styles/styles_test.go +0 -133
- package/internal/testutil/fixture.go +0 -113
- package/internal/testutil/fs.go +0 -26
- package/main.go +0 -117
- package/project-audit/audit_report_glm_5.1.md +0 -411
- package/project-audit/audit_report_opus_4.6 +0 -406
- package/project-audit/consolidated-audit-report.md +0 -456
- package/scripts/vitest-preload.cjs +0 -95
- package/templates/project/.savepoint/Design.md +0 -47
- package/templates/project/.savepoint/PRD.md +0 -34
- package/templates/project/.savepoint/config.yml +0 -27
- package/templates/project/.savepoint/router.md +0 -153
- package/templates/project/.savepoint/visual-identity.md +0 -122
- package/templates/project/AGENTS.md +0 -88
- package/templates/project/agent-skills/savepoint-audit/SKILL.md +0 -87
- package/templates/project/agent-skills/savepoint-build-task/SKILL.md +0 -44
- package/templates/project/agent-skills/savepoint-create-plan/SKILL.md +0 -33
- package/templates/project/agent-skills/savepoint-create-task/SKILL.md +0 -44
- package/templates/project/agent-skills/savepoint-draft-prd/SKILL.md +0 -37
- package/templates/project/agent-skills/savepoint-system-design/SKILL.md +0 -38
- package/templates/prompts/audit-reconciliation.prompt.md +0 -72
- package/templates/prompts/design.prompt.md +0 -45
- package/templates/prompts/epic-design.prompt.md +0 -43
- package/templates/prompts/magic-prompt.prompt.md +0 -7
- package/templates/prompts/prd.prompt.md +0 -42
- package/templates/prompts/task-breakdown.prompt.md +0 -54
- package/templates/prompts/task-building.prompt.md +0 -38
- package/templates/prompts/task-planning.prompt.md +0 -53
- package/templates/release/v1/PRD.md +0 -37
|
@@ -1,456 +0,0 @@
|
|
|
1
|
-
# Consolidated Audit Report — Savepoint
|
|
2
|
-
|
|
3
|
-
This report merges findings from two independent audits (Opus 4.6 and GLM 5.1) of the Savepoint codebase. Where both audits identified the same issue, the finding is merged with combined evidence. Where only one audit identified an issue, it is included with attribution. Severity disagreements are resolved in favour of the higher rating, per the principle that the more cautious assessment should prevail.
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## 1. Executive Summary
|
|
8
|
-
|
|
9
|
-
**Savepoint** is a Go CLI/TUI tool (~5,600 lines of production code, ~5,600 lines of tests, 264 tests across 39 test files) that implements a file-based project state machine with a kanban-style terminal board. It uses the Charmbracelet stack (Bubble Tea, Lip Gloss) for TUI rendering, fsnotify for file watching, and YAML-frontmatter markdown files as its data layer.
|
|
10
|
-
|
|
11
|
-
### What is working well
|
|
12
|
-
|
|
13
|
-
- **File-per-responsibility** is followed diligently. Nearly every `.go` file does one job. The `board/` package splits cleanly into `model.go`, `view.go`, `update.go`, `card.go`, `column.go`, etc.
|
|
14
|
-
- **Test coverage is strong.** 264 tests across 39 files — roughly 1.6× the production code. All packages except `buildtool` and `styles` have tests, and integration tests exist for `board` and `init`.
|
|
15
|
-
- **Clean dependency tree.** Only 2 direct dependencies (`bubbletea`, `fsnotify`) plus the Charmbracelet ecosystem for rendering. No framework bloat.
|
|
16
|
-
- **All tests pass.** `go test ./...` reports zero failures.
|
|
17
|
-
- **Data model is honest.** The `data` package cleanly separates parsing, lifecycle validation, writing, and discovery.
|
|
18
|
-
- **Dependency injection in `cmd/`** via function types (`InitRunner`, `BoardRunner`, `DoctorRunner`) makes commands trivially testable.
|
|
19
|
-
- **Atomic file writes** in `data/write.go` and `init/write.go` prevent corruption.
|
|
20
|
-
- **Policy tests** (`render_policy_test.go`) enforce cross-cutting visual constraints.
|
|
21
|
-
- **Responsive TUI layout** with clean breakpoint-based column rendering.
|
|
22
|
-
|
|
23
|
-
### Biggest risks
|
|
24
|
-
|
|
25
|
-
1. **Synchronous file I/O inside the Bubble Tea `Update()` loop** freezes the TUI on slow disks. This is the highest-impact architectural issue.
|
|
26
|
-
2. **`update.go` is a 521-line monolith** with a deeply nested key-dispatch switch. Hard to extend or test in isolation.
|
|
27
|
-
3. **Duplicated YAML frontmatter read/write/parse logic** appears in `write.go`, `parser.go`, `board.go`, `checks.go`, and `epic_panel.go`.
|
|
28
|
-
4. **Cycle detection in `checks.go` produces inaccurate paths** — a correctness bug.
|
|
29
|
-
5. **No interfaces used for I/O boundaries** — all data-access types are concrete structs, making them impossible to mock without disk fixtures.
|
|
30
|
-
|
|
31
|
-
### Extensibility
|
|
32
|
-
|
|
33
|
-
The project is easy to extend for new checks, overlays, and commands. It is harder to extend for new data sources or rendering backends because I/O is baked into concrete functions. The main risk to extensibility is the `update.go` monolith.
|
|
34
|
-
|
|
35
|
-
### Architecture fit
|
|
36
|
-
|
|
37
|
-
The architecture (flat `internal/` packages, Elm-like TUI model, embedded templates) is well-suited for a small-to-medium CLI tool. No over-engineering is evident. The main architectural debts are the I/O-in-update anti-pattern and the `update.go` size.
|
|
38
|
-
|
|
39
|
-
---
|
|
40
|
-
|
|
41
|
-
## 2. Severity-Ranked Recommendations
|
|
42
|
-
|
|
43
|
-
### Critical
|
|
44
|
-
|
|
45
|
-
#### C1. Synchronous file I/O in the TUI update loop
|
|
46
|
-
|
|
47
|
-
- **Finding:** `update.go` performs filesystem reads and writes directly inside `Update()`: `writeTaskStatus()`, `writeRouterTask()`, `writeRouterReleaseEpic()`, `readEpicDetailFile()`, `selectEpicPanelEpic()`. These block the TUI event loop.
|
|
48
|
-
- **Why it matters:** Any disk latency (network drives, slow SSDs, virus scanners) freezes the entire TUI. Bubble Tea's design intent is for `Update()` to be pure — I/O should happen in `tea.Cmd` functions that return messages.
|
|
49
|
-
- **Evidence:** `internal/board/update.go` (writeRouterTask, writeRouterReleaseEpic, readEpicDetailFile), `internal/board/model.go:235-280` (writeRouterReleaseEpic, writeRouterTask)
|
|
50
|
-
- **Recommended fix:** Extract I/O operations into `tea.Cmd` functions. E.g., `writeTaskStatusCmd(task, path, mtime) tea.Cmd` returns a `tea.Msg` on completion. `Update()` dispatches the command and handles the result message. This is the standard Bubble Tea pattern.
|
|
51
|
-
- **Estimated effort:** Medium
|
|
52
|
-
|
|
53
|
-
#### C2. Cycle detection produces inaccurate paths
|
|
54
|
-
|
|
55
|
-
- **Finding:** `detectCycles` in `checks.go` uses a `parent` map that gets overwritten when a node is visited from multiple paths. When a cycle is found, the path reconstructed via `parent` may not represent the actual cycle.
|
|
56
|
-
- **Why it matters:** Users could be shown a cycle path that doesn't actually exist, causing confusion or incorrect doctor reports.
|
|
57
|
-
- **Evidence:** `internal/doctor/checks.go` — the DFS `parent` map is a simple `map[string]string` that gets overwritten per-visit
|
|
58
|
-
- **Recommended fix:** Use a stack-based cycle reconstruction (track the current DFS path as a slice) or validate the reconstructed path actually forms a cycle before reporting it.
|
|
59
|
-
- **Estimated effort:** Small
|
|
60
|
-
|
|
61
|
-
---
|
|
62
|
-
|
|
63
|
-
### High
|
|
64
|
-
|
|
65
|
-
#### H1. Committed binaries in the repository
|
|
66
|
-
|
|
67
|
-
- **Finding:** `savepoint` (5.5 MB), `savepoint.exe` (6.0 MB), `dist/`, and `ink-cli-ui-design.zip` are tracked in Git.
|
|
68
|
-
- **Why it matters:** Bloats clone size (12+ MB), causes merge noise, and risks accidentally shipping stale binaries.
|
|
69
|
-
- **Evidence:** `.gitignore` does not exclude root binaries. `dist/` is also checked in.
|
|
70
|
-
- **Recommended fix:** Add `savepoint`, `savepoint.exe`, `dist/`, and `*.zip` to `.gitignore`. Run `git rm --cached` on tracked binaries. Build in CI only.
|
|
71
|
-
- **Estimated effort:** Small
|
|
72
|
-
|
|
73
|
-
#### H2. `update.go` complexity: God-method `Update()`
|
|
74
|
-
|
|
75
|
-
- **Finding:** `update.go` is 521 lines. The `Update()` method alone spans ~190 lines with 4+ levels of nesting inside `case tea.KeyMsg`. Overlay handling mixes 5 overlay types in one `updateOverlay()` function.
|
|
76
|
-
- **Why it matters:** Adding a new keybinding or overlay requires editing a deeply nested switch. Bug surface area grows with each addition. The space-bar and backspace handlers have nearly identical structure — find-task-by-ID, mutate, write, refresh.
|
|
77
|
-
- **Evidence:** `internal/board/update.go` — lines 19–192 for `Update()`, lines 132–158 and 159–181 for near-duplicate handler structure
|
|
78
|
-
- **Recommended fix:** Extract key handlers into named methods: `handleAdvanceTask()`, `handleRetreatTask()`, `handleSetPriority()`. Extract `updateBoardKeys()` and `updateOverlayKeys()` from the top-level switch. Split the overlay update into per-type handlers.
|
|
79
|
-
- **Estimated effort:** Medium
|
|
80
|
-
|
|
81
|
-
#### H3. Duplicated frontmatter body-extraction logic
|
|
82
|
-
|
|
83
|
-
- **Finding:** The pattern "extract frontmatter → unmarshal YAML → compute body start offset → reconstruct file" appears in:
|
|
84
|
-
- `write.go:updateFrontmatterField` (lines 40–83)
|
|
85
|
-
- `write.go:WriteTaskStatus` (lines 85–150)
|
|
86
|
-
- `board.go` (router reading)
|
|
87
|
-
- `checks.go` (task validation)
|
|
88
|
-
- `epic_panel.go:epicDetailBody` and `epicAuditBody` (frontmatter stripping, lines 50–60 and 125–134)
|
|
89
|
-
- The magic `delimLen := 4; bodyStart := delimLen + len(raw) + delimLen` appears in two places
|
|
90
|
-
- **Why it matters:** A change to frontmatter format must be patched in 4+ places. The body-offset calculation is fragile.
|
|
91
|
-
- **Evidence:** `internal/data/write.go:74-79` and `internal/data/write.go:140-145` are identical; `internal/board/epic_panel.go:51-59` and `internal/board/epic_panel.go:126-133` are identical
|
|
92
|
-
- **Recommended fix:** Extract `SplitFrontmatterBody(content string) (yaml string, body string, err error)` in the `data` package. Extract `stripFrontmatter(content string) string` for `epic_panel.go`.
|
|
93
|
-
- **Estimated effort:** Small
|
|
94
|
-
|
|
95
|
-
#### H4. No interfaces for data-access types
|
|
96
|
-
|
|
97
|
-
- **Finding:** `Discover`, `Parser`, `ConfigReader`, `RouterReader` are all concrete structs. Every consumer calls `data.NewDiscover()`, `data.NewParser()`, etc. directly.
|
|
98
|
-
- **Why it matters:** Test helpers in `board` and `doctor` must create real filesystem fixtures to test business logic. This is expensive and brittle.
|
|
99
|
-
- **Evidence:** `internal/board/board.go` lines 37, 85, 130 all call `data.NewDiscover()` with no injection point. `internal/doctor/checks.go` lines 116, 293, 454, 525 do the same.
|
|
100
|
-
- **Recommended fix:** Define interfaces at the consumer side (e.g., `type taskDiscoverer interface { ListReleases(root string) ([]data.ReleaseInfo, error) ... }`). Keep the existing structs as production implementations. Accept the interface in board/doctor constructors.
|
|
101
|
-
- **Estimated effort:** Medium
|
|
102
|
-
|
|
103
|
-
#### H5. Stdlib reimplementation in `repairs.go` and `buildtool/main.go`
|
|
104
|
-
|
|
105
|
-
- **Finding:** `contains()` and `indexOf()` in `repairs.go` reimplement `strings.Contains` and `strings.Index`. `trimSpace()` in `buildtool/main.go` reimplements `bytes.TrimSpace`.
|
|
106
|
-
- **Why it matters:** Makes code harder to read for Go developers expecting standard library calls. The custom implementations may have subtle differences from the stdlib versions (e.g., Unicode whitespace handling).
|
|
107
|
-
- **Evidence:** `internal/doctor/repairs.go:50-61`, `internal/buildtool/main.go:211-219`
|
|
108
|
-
- **Recommended fix:** Replace with `strings.Contains`, `strings.Index`, and `strings.TrimSpace` respectively.
|
|
109
|
-
- **Estimated effort:** Small
|
|
110
|
-
|
|
111
|
-
#### H6. Fragile repair suggestion matching via substring search on error messages
|
|
112
|
-
|
|
113
|
-
- **Finding:** `SuggestRepair()` pattern-matches against error message substrings to suggest fixes. If error messages change format, repairs silently break.
|
|
114
|
-
- **Evidence:** `internal/doctor/repairs.go:8-66` — hard-coded substring matching against messages like `"not found"`, `"invalid"`, `"missing"`
|
|
115
|
-
- **Recommended fix:** Define typed error codes or sentinel errors in `data/` and `doctor/`, and match on error type rather than substring.
|
|
116
|
-
- **Estimated effort:** Medium
|
|
117
|
-
|
|
118
|
-
#### H7. Quality gate command execution has no timeout
|
|
119
|
-
|
|
120
|
-
- **Finding:** `RunQualityGates` executes commands from `config.yml` with no timeout. A hung command blocks the doctor indefinitely.
|
|
121
|
-
- **Evidence:** `internal/doctor/gates.go:32-55` — `exec.Command` with `Run()` and no `Context` timeout
|
|
122
|
-
- **Recommended fix:** Use `exec.CommandContext(ctx, ...)` with a configurable timeout (default: 60s). Add a `gate_timeout` config option.
|
|
123
|
-
- **Estimated effort:** Small
|
|
124
|
-
|
|
125
|
-
#### H8. `\r\n` normalization is scattered across files
|
|
126
|
-
|
|
127
|
-
- **Finding:** `strings.ReplaceAll(content, "\r\n", "\n")` appears in `parser.go`, `write.go` (3 times), `epic_panel.go`, and likely elsewhere.
|
|
128
|
-
- **Why it matters:** If the normalization logic changes (e.g., also handling `\r` alone), every call site must be found and updated. Missing a call site causes subtle cross-platform bugs.
|
|
129
|
-
- **Evidence:** `internal/data/parser.go:92`, `internal/data/write.go:22,46,104`, `internal/board/epic_panel.go`
|
|
130
|
-
- **Recommended fix:** Create a `normalizeLineEndings(s string) string` function in `internal/data/` and use it everywhere.
|
|
131
|
-
- **Estimated effort:** Small
|
|
132
|
-
|
|
133
|
-
---
|
|
134
|
-
|
|
135
|
-
### Medium
|
|
136
|
-
|
|
137
|
-
#### M1. `Discover`, `Parser`, `ConfigReader` are stateless singletons instantiated repeatedly
|
|
138
|
-
|
|
139
|
-
- **Finding:** `data.NewDiscover()`, `data.NewParser()`, `data.NewConfigReader()`, `data.NewRouterReader()` all return pointers to zero-value structs. `Discover` is re-created 7 times across `board.go`, `checks.go`, and `main.go`.
|
|
140
|
-
- **Recommended fix:** Either convert to package-level functions (since there's no state) or introduce consumer-side interfaces per H4.
|
|
141
|
-
- **Estimated effort:** Small
|
|
142
|
-
|
|
143
|
-
#### M2. `newProgramModel()` contains hardcoded epic slug
|
|
144
|
-
|
|
145
|
-
- **Finding:** `board.go:33` — `NewModel(nil, "v1", "E03-board-tui-core")` is a development leftover.
|
|
146
|
-
- **Recommended fix:** Delete `newProgramModel()` or replace hardcoded values with empty strings.
|
|
147
|
-
- **Estimated effort:** Small
|
|
148
|
-
|
|
149
|
-
#### M3. Hardcoded state constants in `checks.go` duplicate `data/` definitions
|
|
150
|
-
|
|
151
|
-
- **Finding:** `validStates` map in `checks.go` duplicates state names defined in `data/lifecycle.go`.
|
|
152
|
-
- **Recommended fix:** Remove `validStates` and use `data.IsCanonicalColumn()` / `data.IsCanonicalStage()`.
|
|
153
|
-
- **Estimated effort:** Small
|
|
154
|
-
|
|
155
|
-
#### M4. Inconsistent directory abstraction: `CheckOrphans` bypasses `data.Discover`
|
|
156
|
-
|
|
157
|
-
- **Finding:** Most of `checks.go` uses `data.Discover` for filesystem traversal, but `CheckOrphans` uses `os.ReadDir` directly.
|
|
158
|
-
- **Recommended fix:** Add a `ListRootDirs()` method to `data.Discover` and use it in `CheckOrphans`.
|
|
159
|
-
- **Estimated effort:** Small
|
|
160
|
-
|
|
161
|
-
#### M5. Layout constants split between `layout.go` and `column.go`
|
|
162
|
-
|
|
163
|
-
- **Finding:** `colOverhead` is defined in `column.go` (value 4) and used in both `column.go` and `layout.go`.
|
|
164
|
-
- **Recommended fix:** Move all layout constants to `layout.go`.
|
|
165
|
-
- **Estimated effort:** Small
|
|
166
|
-
|
|
167
|
-
#### M6. `AtomicWrite` cross-device rename fallback is broken
|
|
168
|
-
|
|
169
|
-
- **Finding:** `replaceFile()` tries `os.Rename` first, then falls back to creating a backup and renaming, but `os.Rename` will still fail on cross-device moves in the fallback path.
|
|
170
|
-
- **Evidence:** `internal/init/write.go:52-63`
|
|
171
|
-
- **Recommended fix:** Use `os.Open` + `io.Copy` + `os.Remove` for cross-filesystem fallback.
|
|
172
|
-
- **Estimated effort:** Small
|
|
173
|
-
|
|
174
|
-
#### M7. Ad-hoc Markdown parsing in `epic_panel.go` is fragile
|
|
175
|
-
|
|
176
|
-
- **Finding:** `epicDetailBody()` and `epicAuditBody()` skip headings containing "component" or "files" via substring matching. Any heading with those substrings will be silently hidden.
|
|
177
|
-
- **Recommended fix:** Use exact heading matches with a configurable allowlist/blocklist rather than substring matching.
|
|
178
|
-
- **Estimated effort:** Small (exact match) / Medium (markdown parser)
|
|
179
|
-
|
|
180
|
-
#### M8. `Config.Theme` defaults not filling individual accent colors
|
|
181
|
-
|
|
182
|
-
- **Finding:** `fillThemeDefaults()` fills base theme colors when empty, but for accents it's all-or-nothing: `len(theme.Accents) == 0` triggers the default.
|
|
183
|
-
- **Recommended fix:** Fill missing accent keys individually from `defaultTheme.Accents`.
|
|
184
|
-
- **Estimated effort:** Small
|
|
185
|
-
|
|
186
|
-
#### M9. `splitCommand` in `gates.go` is a naïve shell tokenizer
|
|
187
|
-
|
|
188
|
-
- **Finding:** Only handles double-quote grouping — no escaping, no single quotes, no backslash-escapes.
|
|
189
|
-
- **Recommended fix:** Document the limitation or use `shellwords` parsing.
|
|
190
|
-
- **Estimated effort:** Small
|
|
191
|
-
|
|
192
|
-
#### M10. No Windows build target in `buildtool`
|
|
193
|
-
|
|
194
|
-
- **Finding:** `targets` list only includes Linux and Darwin. No Windows target despite a `localExecutable()` Windows branch.
|
|
195
|
-
- **Recommended fix:** Add Windows amd64 and arm64 targets. Add `.exe` suffix handling.
|
|
196
|
-
- **Estimated effort:** Small
|
|
197
|
-
|
|
198
|
-
#### M11. `buildtool` has no tests
|
|
199
|
-
|
|
200
|
-
- **Finding:** Only production package with `[no test files]`.
|
|
201
|
-
- **Recommended fix:** Add tests for `run()`, `version()`, and `writeTarGz()`.
|
|
202
|
-
|
|
203
|
-
---
|
|
204
|
-
|
|
205
|
-
### Low
|
|
206
|
-
|
|
207
|
-
#### L1. `ColumnType` and `TaskStatus` are parallel enumerations for the same concept
|
|
208
|
-
|
|
209
|
-
- **Recommended fix:** Consider unifying into a single status type. Low priority.
|
|
210
|
-
- **Estimated effort:** Medium
|
|
211
|
-
|
|
212
|
-
#### L2. `package.json` test script is misleading
|
|
213
|
-
|
|
214
|
-
- **Finding:** `"test": "savepoint init"` — `npm test` scaffolds a project instead of running tests.
|
|
215
|
-
- **Recommended fix:** Change to `"test": "echo \"Run 'make test' for Go tests\""`.
|
|
216
|
-
|
|
217
|
-
#### L3. Dead code: `taskLabel()`, `loadAllTasks()`, `newProgramModel()`, `CheckResult`
|
|
218
|
-
|
|
219
|
-
- **Recommended fix:** Delete all four.
|
|
220
|
-
|
|
221
|
-
#### L4. `shortID` and `shortRouterID` are near-duplicates
|
|
222
|
-
|
|
223
|
-
- **Recommended fix:** Consolidate into one `ShortID(full string) string` function.
|
|
224
|
-
|
|
225
|
-
#### L5. `epicIndex` and `releaseIndex` are identical functions
|
|
226
|
-
|
|
227
|
-
- **Recommended fix:** Extract `sliceIndex(items []string, target string) int`.
|
|
228
|
-
|
|
229
|
-
#### L6. No linter configured
|
|
230
|
-
|
|
231
|
-
- **Recommended fix:** Add `.golangci.yml` with `unused`, `errcheck`, `staticcheck`, `govet`, `ineffassign`.
|
|
232
|
-
|
|
233
|
-
#### L7. No distribution checksums
|
|
234
|
-
|
|
235
|
-
- **Finding:** `dist()` creates tar.gz archives but no SHA256 checksums file.
|
|
236
|
-
- **Recommended fix:** Generate `checksums.txt` during `dist`.
|
|
237
|
-
|
|
238
|
-
#### L8. `agent_skills_test.go` hardcodes expected skill count of 6
|
|
239
|
-
|
|
240
|
-
- **Recommended fix:** Remove count assertion or derive from directory listing.
|
|
241
|
-
|
|
242
|
-
#### L9. Test helper duplication across packages
|
|
243
|
-
|
|
244
|
-
- **Recommended fix:** Create `internal/testutil` package with shared fixtures.
|
|
245
|
-
|
|
246
|
-
#### L10. `splitChecklistSentences` doesn't handle abbreviations
|
|
247
|
-
|
|
248
|
-
- **Recommended fix:** Skip periods preceded by known abbreviations (e.g., "e.g.", "i.e.").
|
|
249
|
-
|
|
250
|
-
#### L11. `package main` test file at root level
|
|
251
|
-
|
|
252
|
-
- **Recommended fix:** Move to a dedicated test package.
|
|
253
|
-
|
|
254
|
-
#### L12. Audit section allowlist should be configurable
|
|
255
|
-
|
|
256
|
-
- **Recommended fix:** Extract `allowedSections` to a named constant with documentation.
|
|
257
|
-
|
|
258
|
-
#### L13. `reloadTasks` silently swallows errors
|
|
259
|
-
|
|
260
|
-
- **Finding:** `watch.go` returns `nil` on error, causing the board to silently stop refreshing.
|
|
261
|
-
- **Recommended fix:** Return an `errorMsg` so the TUI can surface it.
|
|
262
|
-
|
|
263
|
-
---
|
|
264
|
-
|
|
265
|
-
## 3. Complexity & Modularity Review
|
|
266
|
-
|
|
267
|
-
### Overly large files
|
|
268
|
-
|
|
269
|
-
| File | Lines | Concern |
|
|
270
|
-
|------|-------|---------|
|
|
271
|
-
| `internal/board/update.go` | 521 | `Update()` is 190 lines; `updateOverlay()` is 100 lines |
|
|
272
|
-
| `internal/doctor/checks.go` | 585 | Single-file check aggregator; could be split by check type |
|
|
273
|
-
| `internal/data/write.go` | 216 | Two large functions with duplicated body-offset arithmetic |
|
|
274
|
-
| `internal/board/epic_panel.go` | 256 | Sidebar, detail, audit, and dropdown rendering mixed |
|
|
275
|
-
|
|
276
|
-
### Tight coupling
|
|
277
|
-
|
|
278
|
-
- **Board → data:** Appropriate for project size. Clean boundary.
|
|
279
|
-
- **Board → os:** `model.go` and `update.go` call `os.ReadFile`, `os.Stat`, `os.WriteFile` directly. Couples UI logic to filesystem.
|
|
280
|
-
|
|
281
|
-
### Repeated logic
|
|
282
|
-
|
|
283
|
-
1. Frontmatter stripping (3+ places)
|
|
284
|
-
2. `\r\n` normalization (4+ call sites across 2 packages)
|
|
285
|
-
3. `shortID` extraction (2 near-duplicate implementations)
|
|
286
|
-
4. `indexOf`/`epicIndex`/`releaseIndex` pattern (3 implementations)
|
|
287
|
-
5. Space-bar and Backspace handlers in `update.go` (nearly identical structure)
|
|
288
|
-
6. `Discover` instantiation (7 separate `NewDiscover()` calls)
|
|
289
|
-
|
|
290
|
-
### Unclear data flow
|
|
291
|
-
|
|
292
|
-
- **`Task.Status` vs `Task.Column`:** Two representations of the same state. `syncTaskStatus` manually keeps them in sync.
|
|
293
|
-
- **`watch.go` silent error swallowing:** `reloadTasks` returns `nil` on error.
|
|
294
|
-
|
|
295
|
-
### Excessive abstraction
|
|
296
|
-
|
|
297
|
-
- `Discover`, `Parser`, `ConfigReader`, `RouterReader` are empty structs used as method namespaces. Should be package-level functions or interfaces.
|
|
298
|
-
|
|
299
|
-
---
|
|
300
|
-
|
|
301
|
-
## 4. Architecture Review
|
|
302
|
-
|
|
303
|
-
### Folder organisation ✅
|
|
304
|
-
|
|
305
|
-
```
|
|
306
|
-
savepoint/
|
|
307
|
-
├── cmd/ # CLI arg parsing — clean separation from execution
|
|
308
|
-
├── internal/
|
|
309
|
-
│ ├── board/ # TUI model/view/update — Elm architecture
|
|
310
|
-
│ ├── buildtool/ # Standalone Go binary for build automation
|
|
311
|
-
│ ├── data/ # Models, parsing, writing, discovery
|
|
312
|
-
│ ├── doctor/ # Read-only diagnostics
|
|
313
|
-
│ ├── init/ # Scaffolding
|
|
314
|
-
│ └── styles/ # Centralised palette + styles
|
|
315
|
-
├── templates/ # Embedded scaffold templates
|
|
316
|
-
└── agent-skills/ # Prompt documents for AI agents
|
|
317
|
-
```
|
|
318
|
-
|
|
319
|
-
### Domain boundaries ✅
|
|
320
|
-
|
|
321
|
-
- **Data layer** (`internal/data/`): Task lifecycle, parsing, discovery, config, writing. Correct boundary.
|
|
322
|
-
- **Board/TUI** (`internal/board/`): Rendering, interaction, file watching. Largest package.
|
|
323
|
-
- **Doctor** (`internal/doctor/`): Checks, gates, repairs, report. Each file has one job. Clean.
|
|
324
|
-
- **Init** (`internal/init/`): Scaffold, validate, write, clipboard, prompt. Clean.
|
|
325
|
-
|
|
326
|
-
### State management
|
|
327
|
-
|
|
328
|
-
Bubble Tea `Model` with 27 fields. Upper bound of manageable. Consider grouping related fields into sub-structs if TUI grows. I/O-in-Update is the main concern (C1).
|
|
329
|
-
|
|
330
|
-
### Configuration approach ✅
|
|
331
|
-
|
|
332
|
-
`config.yml` with defaults baked into Go code. Three-tier color support. `QualityGates` for project-specific commands. Clean.
|
|
333
|
-
|
|
334
|
-
### Error handling
|
|
335
|
-
|
|
336
|
-
Generally good — errors wrapped with `fmt.Errorf("context: %w", err)`. Key exceptions:
|
|
337
|
-
- `reloadTasks` silently swallows errors (L13)
|
|
338
|
-
- `SuggestRepair` relies on substring matching (H6)
|
|
339
|
-
- Quality gates have no timeout (H7)
|
|
340
|
-
|
|
341
|
-
---
|
|
342
|
-
|
|
343
|
-
## 5. Best-Practice Review
|
|
344
|
-
|
|
345
|
-
### Framework conventions ⚠️
|
|
346
|
-
|
|
347
|
-
Bubble Tea conventions generally followed. I/O in `Update()` violates the framework's core principle — see C1.
|
|
348
|
-
|
|
349
|
-
### Type security ✅
|
|
350
|
-
|
|
351
|
-
Custom types (`ColumnType`, `ProgressStage`, `OverlayType`) used appropriately. `ColumnType`/`TaskStatus` duality is a minor concern (L1).
|
|
352
|
-
|
|
353
|
-
### Linting/formatting ⚠️
|
|
354
|
-
|
|
355
|
-
No linter configured. Add `.golangci.yml` with `unused`, `errcheck`, `staticcheck`, `govet`, `ineffassign`.
|
|
356
|
-
|
|
357
|
-
### Testing ✅
|
|
358
|
-
|
|
359
|
-
Strong coverage (264 tests, ~1.6:1 test-to-code ratio). Missing: `buildtool`, `styles`, benchmarks, fuzz tests.
|
|
360
|
-
|
|
361
|
-
### Dependency management ✅
|
|
362
|
-
|
|
363
|
-
`go.mod` is clean. 2 direct dependencies. All indirect deps from Charmbracelet ecosystem.
|
|
364
|
-
|
|
365
|
-
### Build/deployment ⚠️
|
|
366
|
-
|
|
367
|
-
- No CI configuration visible
|
|
368
|
-
- Binaries committed to repo (H1)
|
|
369
|
-
- No Windows build target (M10)
|
|
370
|
-
- No distribution checksums (L7)
|
|
371
|
-
|
|
372
|
-
### Logging/debugging ⚠️
|
|
373
|
-
|
|
374
|
-
No logging. TUI uses `StatusMessage` for user feedback. No `--debug` flag. Recommend adding `SAVEPOINT_DEBUG` env var.
|
|
375
|
-
|
|
376
|
-
---
|
|
377
|
-
|
|
378
|
-
## 6. Refactor Roadmap
|
|
379
|
-
|
|
380
|
-
### Phase 1 — Safe cleanup
|
|
381
|
-
|
|
382
|
-
**Objective:** Remove dead code, fix obvious duplication, improve hygiene.
|
|
383
|
-
|
|
384
|
-
| Task | Risk |
|
|
385
|
-
|------|------|
|
|
386
|
-
| Add binaries to `.gitignore` and remove from Git tracking | None |
|
|
387
|
-
| Delete `taskLabel()`, `loadAllTasks()`, `newProgramModel()`, `CheckResult` | None |
|
|
388
|
-
| Remove unused `exitCode` param from `GateSuggestion` | None |
|
|
389
|
-
| Replace `contains()`/`indexOf()` with `strings.Contains`/`strings.Index` | None |
|
|
390
|
-
| Replace `trimSpace()` with `strings.TrimSpace` | None |
|
|
391
|
-
| Replace `validStates` map with `data.IsCanonicalColumn()`/`data.IsCanonicalStage()` | Low |
|
|
392
|
-
| Fix `package.json` test script | None |
|
|
393
|
-
| Add `.golangci.yml` with basic linters | None |
|
|
394
|
-
| Co-locate layout constants (`colOverhead`) into `layout.go` | Low |
|
|
395
|
-
| Consolidate `shortID`/`shortRouterID` and `epicIndex`/`releaseIndex` | Low |
|
|
396
|
-
|
|
397
|
-
**Expected benefit:** Cleaner codebase, smaller repo, automated lint catches.
|
|
398
|
-
**Risk level:** Very low.
|
|
399
|
-
|
|
400
|
-
### Phase 2 — Structural improvements
|
|
401
|
-
|
|
402
|
-
**Objective:** Reduce duplication, improve modularity, make key files easier to extend.
|
|
403
|
-
|
|
404
|
-
| Task | Risk |
|
|
405
|
-
|------|------|
|
|
406
|
-
| Extract `SplitFrontmatterBody()` in `data` package | Low — well-tested |
|
|
407
|
-
| Extract `stripFrontmatter()` for `epic_panel.go` | Low |
|
|
408
|
-
| Add `normalizeLineEndings()` to `data` package; use everywhere | Low |
|
|
409
|
-
| Split `Update()` into `handleBoardKey()`, `handleOverlayKey()`, named methods | Medium |
|
|
410
|
-
| Group `Model` fields into sub-structs | Medium |
|
|
411
|
-
| Convert stateless data types to package-level functions or consumer-defined interfaces | Medium |
|
|
412
|
-
| Fix `AtomicWrite` cross-device fallback | Low |
|
|
413
|
-
| Make `Config.Theme.Accents` fill missing keys individually | Low |
|
|
414
|
-
|
|
415
|
-
**Expected benefit:** Easier to add features, reduced duplication, more testable.
|
|
416
|
-
**Risk level:** Medium.
|
|
417
|
-
|
|
418
|
-
### Phase 3 — Hardening
|
|
419
|
-
|
|
420
|
-
**Objective:** Fix the I/O-in-update anti-pattern, add missing tests, improve error handling.
|
|
421
|
-
|
|
422
|
-
| Task | Risk |
|
|
423
|
-
|------|------|
|
|
424
|
-
| Extract all filesystem I/O from `update.go` into `tea.Cmd` functions | Medium-High |
|
|
425
|
-
| Add `tea.Cmd`-based router writing for priority key and epic selection | Medium |
|
|
426
|
-
| Handle `reloadTasks` errors by emitting `errorMsg` | Low |
|
|
427
|
-
| Add timeout to quality gate execution | Low |
|
|
428
|
-
| Convert `SuggestRepair` to typed error matching | Medium |
|
|
429
|
-
| Add tests for `buildtool/` | Low |
|
|
430
|
-
| Add tests for `styles/` | Low |
|
|
431
|
-
| Add benchmark tests for render functions | Low |
|
|
432
|
-
| Add fuzz targets for YAML frontmatter parsing | Low |
|
|
433
|
-
| Add `--debug`/`SAVEPOINT_DEBUG` flag | Low |
|
|
434
|
-
| Fix cycle detection path reconstruction | Low |
|
|
435
|
-
|
|
436
|
-
**Expected benefit:** TUI responsiveness, correct error propagation, test coverage completeness.
|
|
437
|
-
**Risk level:** Low–Medium.
|
|
438
|
-
|
|
439
|
-
---
|
|
440
|
-
|
|
441
|
-
## 7. Top 10 Action List
|
|
442
|
-
|
|
443
|
-
- [ ] **1. Extract I/O from `update.go` into `tea.Cmd` functions** — Critical — `internal/board/update.go`, `internal/board/model.go` — Prevents TUI freezes on slow disk; follows Bubble Tea conventions; highest architectural impact
|
|
444
|
-
- [ ] **2. Remove committed binaries from the repository** — High — `.gitignore`, `savepoint`, `savepoint.exe`, `dist/`, `ink-cli-ui-design.zip` — Repo shrinks by 12 MB+, eliminates merge noise
|
|
445
|
-
- [ ] **3. Fix cycle detection path reconstruction in `checks.go`** — High (bug) — `internal/doctor/checks.go` — Produces inaccurate error messages today
|
|
446
|
-
- [ ] **4. Extract `SplitFrontmatterBody()` to deduplicate write logic** — High — `internal/data/write.go`, `internal/board/epic_panel.go` — Single source of truth for frontmatter reconstruction
|
|
447
|
-
- [ ] **5. Split `Update()` into named key-handler methods** — High — `internal/board/update.go` — 190-line method becomes 5–6 focused methods; easier to extend
|
|
448
|
-
- [ ] **6. Replace stdlib reimplementations (`contains`, `indexOf`, `trimSpace`)** — High — `internal/doctor/repairs.go`, `internal/buildtool/main.go` — Eliminates confusing custom code
|
|
449
|
-
- [ ] **7. Add timeout to quality gate execution** — High — `internal/doctor/gates.go` — Prevents indefinite blocking
|
|
450
|
-
- [ ] **8. Centralize `\r\n` normalization and frontmatter stripping** — Medium — `internal/data/parser.go`, `internal/data/write.go`, `internal/board/epic_panel.go` — Single source of truth for cross-platform line endings and body extraction
|
|
451
|
-
- [ ] **9. Consolidate layout constants, shared utilities, and duplicate functions** — Medium — `internal/board/column.go`, `internal/board/layout.go`, `internal/board/card.go`, `internal/board/view.go`, `internal/board/detail.go`, `internal/board/epic_panel.go`, `internal/board/release.go` — Reduces scatter and makes logic findable
|
|
452
|
-
- [ ] **10. Fix `AtomicWrite` cross-device rename fallback** — Medium — `internal/init/write.go` — Prevents silent data loss on cross-filesystem moves
|
|
453
|
-
|
|
454
|
-
---
|
|
455
|
-
|
|
456
|
-
*Consolidated from audits by Opus 4.6 and GLM 5.1 on 2026-05-03.*
|
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
const childProcess = require("node:child_process");
|
|
2
|
-
const esbuild = require("esbuild");
|
|
3
|
-
|
|
4
|
-
const originalExec = childProcess.exec;
|
|
5
|
-
const originalExecFile = childProcess.execFile;
|
|
6
|
-
|
|
7
|
-
function shouldStub(command) {
|
|
8
|
-
return (
|
|
9
|
-
typeof command === "string" && command.trim().toLowerCase() === "net use"
|
|
10
|
-
);
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
function fakeChildProcess() {
|
|
14
|
-
return {
|
|
15
|
-
pid: 0,
|
|
16
|
-
kill() {
|
|
17
|
-
return true;
|
|
18
|
-
},
|
|
19
|
-
stdin: null,
|
|
20
|
-
stdout: null,
|
|
21
|
-
stderr: null,
|
|
22
|
-
on() {
|
|
23
|
-
return this;
|
|
24
|
-
},
|
|
25
|
-
once() {
|
|
26
|
-
return this;
|
|
27
|
-
},
|
|
28
|
-
addListener() {
|
|
29
|
-
return this;
|
|
30
|
-
},
|
|
31
|
-
removeListener() {
|
|
32
|
-
return this;
|
|
33
|
-
},
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
// Vitest probes `net use` on Windows to detect network drive mappings, which fails in this scaffold.
|
|
38
|
-
childProcess.exec = function exec(command, options, callback) {
|
|
39
|
-
if (shouldStub(command)) {
|
|
40
|
-
const done = typeof options === "function" ? options : callback;
|
|
41
|
-
if (typeof done === "function") {
|
|
42
|
-
setImmediate(() => done(null, "", ""));
|
|
43
|
-
}
|
|
44
|
-
return fakeChildProcess();
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
return originalExec.call(this, command, options, callback);
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
childProcess.execFile = function execFile(file, args, options, callback) {
|
|
51
|
-
if (shouldStub(file)) {
|
|
52
|
-
const done =
|
|
53
|
-
typeof args === "function"
|
|
54
|
-
? args
|
|
55
|
-
: typeof options === "function"
|
|
56
|
-
? options
|
|
57
|
-
: callback;
|
|
58
|
-
if (typeof done === "function") {
|
|
59
|
-
setImmediate(() => done(null, "", ""));
|
|
60
|
-
}
|
|
61
|
-
return fakeChildProcess();
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
return originalExecFile.call(this, file, args, options, callback);
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
function identityTransform(input) {
|
|
68
|
-
const code =
|
|
69
|
-
typeof input === "string" ? input : (input?.toString("utf8") ?? "");
|
|
70
|
-
return Promise.resolve({
|
|
71
|
-
code,
|
|
72
|
-
map: "",
|
|
73
|
-
warnings: [],
|
|
74
|
-
errors: [],
|
|
75
|
-
mangleCache: {},
|
|
76
|
-
legalComments: "none",
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
function identityTransformSync(input) {
|
|
81
|
-
const code =
|
|
82
|
-
typeof input === "string" ? input : (input?.toString("utf8") ?? "");
|
|
83
|
-
return {
|
|
84
|
-
code,
|
|
85
|
-
map: "",
|
|
86
|
-
warnings: [],
|
|
87
|
-
errors: [],
|
|
88
|
-
mangleCache: {},
|
|
89
|
-
legalComments: "none",
|
|
90
|
-
};
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
// Vitest reaches into esbuild on Windows before the real transform path is ready.
|
|
94
|
-
esbuild.transform = identityTransform;
|
|
95
|
-
esbuild.transformSync = identityTransformSync;
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: project-design
|
|
3
|
-
status: active
|
|
4
|
-
last_audited: never
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
# {{PROJECT_NAME}} — System Architecture
|
|
8
|
-
|
|
9
|
-
> Project-level architecture. Audit-kept fresh: every epic's audit step merges its delta into this document.
|
|
10
|
-
>
|
|
11
|
-
> **Visual identity** lives separately in `.savepoint/visual-identity.md` and is loaded only for TUI/theme/visual tasks.
|
|
12
|
-
|
|
13
|
-
## 1. Architecture model
|
|
14
|
-
|
|
15
|
-
<!-- High-level architecture pattern. -->
|
|
16
|
-
|
|
17
|
-
## 2. Directory layout
|
|
18
|
-
|
|
19
|
-
<!-- Expected file structure. -->
|
|
20
|
-
|
|
21
|
-
## 3. Hierarchy semantics
|
|
22
|
-
|
|
23
|
-
<!-- Definitions of release, epic, task, sub-task. -->
|
|
24
|
-
|
|
25
|
-
## 4. Status model & gates
|
|
26
|
-
|
|
27
|
-
<!-- How work moves through states. -->
|
|
28
|
-
|
|
29
|
-
## 5. Dependencies
|
|
30
|
-
|
|
31
|
-
<!-- How tasks depend on each other. -->
|
|
32
|
-
|
|
33
|
-
## 6. CLI surface
|
|
34
|
-
|
|
35
|
-
<!-- Commands and flags if applicable. -->
|
|
36
|
-
|
|
37
|
-
## 7. Agent audit workflow
|
|
38
|
-
|
|
39
|
-
<!-- Savepoint audit is agent-led and skill-driven, not a CLI pipeline. At epic close, a fresh audit agent writes one epic-local `E##-Audit.md` with exactly these user-facing sections: `## Main Findings` and `## Code Style Review`. File-specific `### Target File` / `### Replace` / `### With` blocks belong under a separate `## Proposed Changes` admin section so the TUI Audit tab can omit them. -->
|
|
40
|
-
|
|
41
|
-
## 8. Testing strategy
|
|
42
|
-
|
|
43
|
-
<!-- How the project is tested. -->
|
|
44
|
-
|
|
45
|
-
## 9. Release versioning
|
|
46
|
-
|
|
47
|
-
<!-- Version scheme. -->
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: project-prd
|
|
3
|
-
status: active
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# {{PROJECT_NAME}} — Product Vision
|
|
7
|
-
|
|
8
|
-
## What it is
|
|
9
|
-
|
|
10
|
-
<!-- Describe what you are building in one paragraph. Be specific about the core mechanic (e.g., "A CLI tool that uses AI to write unit tests" instead of "An AI coding assistant"). -->
|
|
11
|
-
|
|
12
|
-
## Why
|
|
13
|
-
|
|
14
|
-
<!-- What specific problem does this solve? Why does it need to exist now? (e.g., "Developers skip writing tests because it's tedious; this automates the drudgery so coverage stays high without the manual effort.") -->
|
|
15
|
-
|
|
16
|
-
## Target user
|
|
17
|
-
|
|
18
|
-
<!-- Who is this for? Be specific. (e.g., "Vibe coders," "Junior frontend developers," "Indie hackers building SaaS MVPs"). If it's for everyone, it's for no one. -->
|
|
19
|
-
|
|
20
|
-
## Headline differentiator
|
|
21
|
-
|
|
22
|
-
<!-- What makes this project unique? Why would someone use this over an existing alternative? (e.g., "It integrates directly into the savepoint audit loop, whereas others require a separate PR step.") -->
|
|
23
|
-
|
|
24
|
-
## Success metrics
|
|
25
|
-
|
|
26
|
-
<!-- How do you know it's working for V1? (e.g., "Can generate a passing test suite for a 10-file React app in under 60 seconds with zero manual edits.") -->
|
|
27
|
-
|
|
28
|
-
## Constraints
|
|
29
|
-
|
|
30
|
-
<!-- Hard limits. What tech stack MUST be used? Are there API cost limits, token limits, or specific libraries you refuse to use? -->
|
|
31
|
-
|
|
32
|
-
## Out of scope (forever or for now)
|
|
33
|
-
|
|
34
|
-
<!-- What are you explicitly NOT building for V1? (e.g., "No database. No multi-user login. No web UI.") This is crucial for keeping the AI focused. -->
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
# Savepoint config — single source of truth for project preferences.
|
|
2
|
-
|
|
3
|
-
verify_strict: false # vibe-coder soft mode; tasks reach done on assertion. Set true for TDD-strict.
|
|
4
|
-
|
|
5
|
-
quality_gates:
|
|
6
|
-
lint: null
|
|
7
|
-
typecheck: null
|
|
8
|
-
test: null
|
|
9
|
-
block_on_failure: true
|
|
10
|
-
|
|
11
|
-
audit:
|
|
12
|
-
divergence_threshold: 0.5 # warn if a proposal changes >50% of a live file
|
|
13
|
-
|
|
14
|
-
theme:
|
|
15
|
-
bg: "#121212"
|
|
16
|
-
surface: "#0D0D0D"
|
|
17
|
-
surface_2: "#0F0F0F"
|
|
18
|
-
border: "#1A1A1A"
|
|
19
|
-
text: "#F0E6DA"
|
|
20
|
-
accents:
|
|
21
|
-
backlog: "#B1A1DF"
|
|
22
|
-
planned: "#B1A1DF"
|
|
23
|
-
in_progress: "#FC6323"
|
|
24
|
-
review: "#FC6323"
|
|
25
|
-
done: "#A4C639"
|
|
26
|
-
blocked: "#FF4444"
|
|
27
|
-
borders: "subtle"
|