savepoint 1.0.0 → 1.0.1
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/.claude/settings.local.json +5 -1
- package/.savepoint/Design.md +8 -4
- package/.savepoint/audit/E06-atari-noir-layout/proposals.md +130 -0
- package/.savepoint/audit/E06-atari-noir-layout/snapshot.md +84 -0
- package/.savepoint/config.yml +3 -3
- package/.savepoint/releases/v1/epics/E06-atari-noir-layout/Design.md +24 -6
- package/.savepoint/releases/v1/epics/E06-atari-noir-layout/tasks/T007-detail-card-fixes.md +7 -7
- package/.savepoint/releases/v1/epics/E06-atari-noir-layout/tasks/T008-checkbox-states.md +10 -8
- package/.savepoint/releases/v1/epics/E06-atari-noir-layout/tasks/T009-router-priority-marker.md +16 -9
- package/.savepoint/releases/v1/epics/E06-atari-noir-layout/tasks/T010-auto-refresh-watcher.md +25 -22
- package/.savepoint/releases/v1.1/epics/E01-tui-optimisation/Design.md +10 -4
- package/.savepoint/releases/v1.1/epics/E01-tui-optimisation/tasks/T001-border-resize-fix.md +2 -1
- package/.savepoint/releases/v1.1/epics/E01-tui-optimisation/tasks/T002-rename-epic-design-files.md +38 -0
- package/.savepoint/releases/v1.1/epics/E01-tui-optimisation/tasks/T003-rename-release-prd.md +28 -0
- package/.savepoint/releases/v1.1/epics/E01-tui-optimisation/tasks/T004-update-instruction-files.md +50 -0
- package/.savepoint/releases/v1.1/epics/E01-tui-optimisation/tasks/T005-update-cross-references.md +44 -0
- package/.savepoint/releases/v1.1/epics/E01-tui-optimisation/tasks/T006-column-and-detail-scrolling.md +58 -0
- package/.savepoint/releases/v1.1/epics/E01-tui-optimisation/tasks/T007-next-activity-header.md +55 -0
- package/.savepoint/releases/v1.1/epics/E02-cross-platform-compatibility/Design.md +40 -0
- package/.savepoint/releases/v1.1/epics/E02-cross-platform-compatibility/tasks/T001-fix-makefile.md +34 -0
- package/.savepoint/releases/v1.1/epics/E02-cross-platform-compatibility/tasks/T002-linux-build-target.md +33 -0
- package/.savepoint/releases/v1.1/epics/E02-cross-platform-compatibility/tasks/T003-macos-build-target.md +32 -0
- package/.savepoint/releases/v1.1/epics/E02-cross-platform-compatibility/tasks/T004-smoke-tests-and-artifacts.md +38 -0
- package/.savepoint/router.md +1 -1
- package/.savepoint/visual-identity.md +4 -3
- package/AGENTS.md +3 -3
- package/README.md +1 -1
- package/go.mod +4 -1
- package/go.sum +2 -0
- package/internal/board/board.go +42 -6
- package/internal/board/board_test.go +53 -0
- package/internal/board/card.go +9 -3
- package/internal/board/card_test.go +28 -14
- package/internal/board/column.go +2 -2
- package/internal/board/column_test.go +17 -9
- package/internal/board/detail.go +21 -11
- package/internal/board/detail_test.go +30 -14
- package/internal/board/model.go +7 -1
- package/internal/board/update.go +24 -1
- package/internal/board/view.go +13 -3
- package/internal/board/view_test.go +2 -2
- package/internal/board/watch.go +82 -0
- package/internal/data/parser.go +31 -1
- package/internal/data/parser_test.go +8 -2
- package/internal/data/task.go +12 -2
- package/internal/styles/palette.go +6 -4
- package/internal/styles/styles.go +5 -15
- package/package.json +5 -4
- package/savepoint +0 -0
|
@@ -14,7 +14,11 @@
|
|
|
14
14
|
"Bash(node --require ./scripts/vitest-preload.cjs ./node_modules/vitest/vitest.mjs run --configLoader runner --config vitest.config.js)",
|
|
15
15
|
"Bash(go test *)",
|
|
16
16
|
"Bash(go build *)",
|
|
17
|
-
"Bash(go vet *)"
|
|
17
|
+
"Bash(go vet *)",
|
|
18
|
+
"Bash(make build *)",
|
|
19
|
+
"Bash(make test *)",
|
|
20
|
+
"Bash(go get *)",
|
|
21
|
+
"Bash(go doc *)"
|
|
18
22
|
]
|
|
19
23
|
}
|
|
20
24
|
}
|
package/.savepoint/Design.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
type: project-design
|
|
3
3
|
status: active
|
|
4
|
-
last_audited:
|
|
4
|
+
last_audited: E06-atari-noir-layout (2026-05-02)
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Savepoint — System Architecture
|
|
@@ -23,7 +23,7 @@ last_audited: E02-data-readers (2026-05-01)
|
|
|
23
23
|
- **Go data-reader boundary:** established in epic `E02-data-readers` (2026-05-01). `internal/data` owns Savepoint file parsing and discovery for the Go implementation: task frontmatter models, markdown YAML extraction, router state parsing, config theme defaults, release/epic/task directory listing, and boundary error sentinels.
|
|
24
24
|
- **Template assets** live under `templates/` with helpers in `src/templates/` (epic E04).
|
|
25
25
|
- **Init command** (`savepoint init`) validates, scaffolds, prints prompt, clipboard, optional install (epic E05).
|
|
26
|
-
- **Board command** (`savepoint board`) reads project,
|
|
26
|
+
- **Board command** (`savepoint board`) reads project state, renders the Atari-Noir TUI board, supports release/epic filtering, detail overlays, task status transitions with mtime-guarded writes, router priority markers, and fsnotify-based task auto-refresh (epic E06).
|
|
27
27
|
- **Audit pipeline** (`savepoint audit`) resolves epic, skips, quality gates, snapshots, router transition, proposal review (epic E07).
|
|
28
28
|
|
|
29
29
|
## 2. Directory layout
|
|
@@ -131,9 +131,13 @@ Acknowledged terminal limits: fonts, scanlines, glows, letter-spacing, mouse-dri
|
|
|
131
131
|
|
|
132
132
|
**Render fallbacks:** 256-color → 16-color hard-coded → `NO_COLOR=1` monochrome with glyphs → non-TTY plain table.
|
|
133
133
|
|
|
134
|
-
**Layout:** single screen with a
|
|
134
|
+
**Layout:** single screen with a 3-column task board (`planned`, `in_progress`, `done`), optional epic sidebar on wide terminals, centered overlays for release/epic/help/task detail, static Atari-Noir header/footer, full-width dividers, uniform black TUI backgrounds, and navigation hints. Non-TTY output remains a plain table fallback.
|
|
135
135
|
|
|
136
|
-
**
|
|
136
|
+
**Visual guardrail:** the terminal board intentionally uses one black background for Background, Surface, and Surface 2. Do not restore subtly different dark panel fills; depth should come from spacing, dividers, glyphs, and focused Atari Orange borders.
|
|
137
|
+
|
|
138
|
+
**Board persistence and refresh:** task status transitions write canonical task frontmatter through `internal/data.WriteTaskStatus` with mtime conflict checks. The board watches `.savepoint/releases/` recursively with fsnotify and reloads task data after debounced file changes.
|
|
139
|
+
|
|
140
|
+
**Implementation modules:** see AGENTS.md Codebase Map.
|
|
137
141
|
|
|
138
142
|
**Keybindings:** arrow/vim navigation, enter advances, backspace retreats, r/R refreshes, a/A exits toward audit review when proposals exist, q quits.
|
|
139
143
|
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
# E06 Atari-Noir Layout Audit Proposals
|
|
2
|
+
|
|
3
|
+
## Target File
|
|
4
|
+
|
|
5
|
+
`.savepoint/Design.md`
|
|
6
|
+
|
|
7
|
+
## Replace
|
|
8
|
+
|
|
9
|
+
```md
|
|
10
|
+
- **Board command** (`savepoint board`) reads project, non-TTY fallback, Ink TUI, transition gates, mtime writes, audit signaling (epic E06).
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## With
|
|
14
|
+
|
|
15
|
+
```md
|
|
16
|
+
- **Board command** (`savepoint board`) reads project state, renders the Atari-Noir TUI board, supports release/epic filtering, detail overlays, task status transitions with mtime-guarded writes, router priority markers, and fsnotify-based task auto-refresh (epic E06).
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Target File
|
|
20
|
+
|
|
21
|
+
`.savepoint/Design.md`
|
|
22
|
+
|
|
23
|
+
## Replace
|
|
24
|
+
|
|
25
|
+
```md
|
|
26
|
+
**Layout:** single screen with a 5-column Kanban board and detail pane. Non-TTY output uses `src/tui/render/plain-table.ts`.
|
|
27
|
+
|
|
28
|
+
**Implementation modules:** see AGENTS.md Codebase Map (E06 and E07 epic rows).
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## With
|
|
32
|
+
|
|
33
|
+
```md
|
|
34
|
+
**Layout:** single screen with a 3-column task board (`planned`, `in_progress`, `done`), optional epic sidebar on wide terminals, centered overlays for release/epic/help/task detail, static Atari-Noir header/footer, and navigation hints. Non-TTY output remains a plain table fallback.
|
|
35
|
+
|
|
36
|
+
**Board persistence and refresh:** task status transitions write canonical task frontmatter through `internal/data.WriteTaskStatus` with mtime conflict checks. The board watches `.savepoint/releases/` recursively with fsnotify and reloads task data after debounced file changes.
|
|
37
|
+
|
|
38
|
+
**Implementation modules:** see AGENTS.md Codebase Map.
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Target File
|
|
42
|
+
|
|
43
|
+
`AGENTS.md`
|
|
44
|
+
|
|
45
|
+
## Replace
|
|
46
|
+
|
|
47
|
+
```md
|
|
48
|
+
| `internal/board/` | TUI board components, models, layouts, transitions, and rendering logic |
|
|
49
|
+
| `internal/data/` | Task data models, frontmatter parsing, project configuration, routing, and generic file readers |
|
|
50
|
+
| `internal/styles/` | Shared visual design system, TUI styling, and palettes |
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## With
|
|
54
|
+
|
|
55
|
+
```md
|
|
56
|
+
| `internal/board/` | TUI board models, layout, rendering, overlays, task transitions, router priority markers, and fsnotify refresh |
|
|
57
|
+
| `internal/data/` | Task/router/config models, frontmatter parsing, checklist state parsing, mtime-guarded writes, discovery, and generic file readers |
|
|
58
|
+
| `internal/styles/` | Atari-Noir palette constants, terminal color fallbacks, shared TUI styles, semantic glyph/tag styles, and footer/header styling |
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Target File
|
|
62
|
+
|
|
63
|
+
`.savepoint/releases/v1/epics/E06-atari-noir-layout/Design.md`
|
|
64
|
+
|
|
65
|
+
## Replace
|
|
66
|
+
|
|
67
|
+
```md
|
|
68
|
+
# Epic E07: Atari-Noir Layout Uplift
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## With
|
|
72
|
+
|
|
73
|
+
```md
|
|
74
|
+
# Epic E06: Atari-Noir Layout Uplift
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Target File
|
|
78
|
+
|
|
79
|
+
`.savepoint/releases/v1/epics/E06-atari-noir-layout/Design.md`
|
|
80
|
+
|
|
81
|
+
## Insert After
|
|
82
|
+
|
|
83
|
+
```md
|
|
84
|
+
| `internal/board/epic_panel.go` | Refine epic panel layout |
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## With
|
|
88
|
+
|
|
89
|
+
```md
|
|
90
|
+
|
|
91
|
+
## Implemented As
|
|
92
|
+
|
|
93
|
+
- `internal/styles/palette.go` defines the Atari-Noir hex palette plus ANSI256/ANSI16 fallbacks.
|
|
94
|
+
- `internal/styles/styles.go` centralizes header, divider, footer, column, card, detail, glyph, and semantic tag styles.
|
|
95
|
+
- `internal/board/view.go` renders the static SavePoint header, the static `PLAN │ BUILD │ AUDIT` footer, subdued navigation hints, and overlay composition.
|
|
96
|
+
- `internal/board/card.go` wraps long task titles instead of truncating them and uses a green `▣` marker for the router-priority task.
|
|
97
|
+
- `internal/board/detail.go` adds spacing below Acceptance Criteria and Implementation Plan headings, renders checklist state with `☑`/`□`, and labels the router-priority task.
|
|
98
|
+
- `internal/data/task.go` and `internal/data/parser.go` represent Implementation Plan items as `CheckItem{Text, Done}` and parse `- [x]`, `- [ ]`, and legacy `- ` items.
|
|
99
|
+
- `internal/data/write.go` persists task status and phase changes with mtime conflict protection.
|
|
100
|
+
- `internal/board/watch.go` adds fsnotify-based recursive release directory watching, 100ms debounce, and reload messages used by `internal/board/update.go`.
|
|
101
|
+
|
|
102
|
+
## Implementation Deltas
|
|
103
|
+
|
|
104
|
+
- The original visual-only scope expanded to include board usability fixes requested during E06: footer navigation hints, detail overlay spacing, card title word-wrap, checklist state rendering, router priority markers, and auto-refresh on task file changes.
|
|
105
|
+
- The current implementation still uses rounded frames/borders on header, board, columns, cards, and epic panel. That differs from the design language of "unnecessary borders removed" and should be reconciled before closing the visual uplift.
|
|
106
|
+
- `styles.Divider` exists but the main view does not render explicit full-width top/bottom divider lines; divider-like output currently comes from framed containers and component separators.
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Quality Review
|
|
110
|
+
|
|
111
|
+
## Must Fix Before Close
|
|
112
|
+
|
|
113
|
+
- None remaining after approval closeout.
|
|
114
|
+
|
|
115
|
+
## Carry Forward
|
|
116
|
+
|
|
117
|
+
- `internal/board/watch.go:17`: watcher errors are consumed silently. This is acceptable for v1 audit as non-blocking resilience, but a future task should surface watcher failures in `StatusMessage` or diagnostics.
|
|
118
|
+
- `internal/board/update.go:68` and `internal/board/update.go:84`: `ErrMtimeConflict` is intentionally non-destructive, but the user receives no visible conflict message because that error is ignored. Consider showing a manual-refresh message so conflicts are understandable.
|
|
119
|
+
- `go.mod`: `github.com/fsnotify/fsnotify` is currently listed as indirect even though project code imports it directly. `go mod tidy` may fix this metadata.
|
|
120
|
+
- Root instruction drift: `AGENTS.md` references `agent-skills/audit/SKILL.md`, but the repository contains `agent-skills/savepoint-audit/SKILL.md`.
|
|
121
|
+
|
|
122
|
+
## Already Fixed
|
|
123
|
+
|
|
124
|
+
- `go build ./...`: PASS during audit.
|
|
125
|
+
- `go test ./...`: PASS during audit.
|
|
126
|
+
- Approval closeout added explicit full-width divider lines rendered through `styles.Divider`.
|
|
127
|
+
- Approval closeout removed unnecessary borders from unfocused header, board, column, card, and epic panel surfaces while preserving focused Atari Orange borders.
|
|
128
|
+
- T008 checklist parsing preserves checked/unchecked state in `data.CheckItem` and renders checked items distinctly.
|
|
129
|
+
- T009 router priority marker is wired through model, card, column, and detail rendering.
|
|
130
|
+
- T010 auto-refresh watcher is isolated in `internal/board/watch.go` and cleanly disabled in tests when `Model.Watcher` is nil.
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: audit-snapshot
|
|
3
|
+
release: v1
|
|
4
|
+
epic: E06-atari-noir-layout
|
|
5
|
+
created: 2026-05-02
|
|
6
|
+
mode: manual
|
|
7
|
+
reason: "Audit CLI snapshot was unavailable; router authorized one manual snapshot from known epic scope."
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# E06 Atari-Noir Layout Snapshot
|
|
11
|
+
|
|
12
|
+
## Router State
|
|
13
|
+
|
|
14
|
+
- `state`: `audit-pending`
|
|
15
|
+
- `release`: `v1`
|
|
16
|
+
- `epic`: `E06-atari-noir-layout`
|
|
17
|
+
- `task`: `E06-atari-noir-layout/T010-auto-refresh-watcher`
|
|
18
|
+
- `next_action`: All E06 tasks done. Start new agent session for epic audit.
|
|
19
|
+
|
|
20
|
+
## Epic Scope
|
|
21
|
+
|
|
22
|
+
E06 implemented the Atari-Noir TUI layout uplift and related board usability fixes:
|
|
23
|
+
|
|
24
|
+
- Atari-Noir palette/style usage in `internal/styles/`.
|
|
25
|
+
- Header/footer rendering, navigation hints, and board layout adjustments in `internal/board/view.go`.
|
|
26
|
+
- Card title wrapping and detail overlay spacing/checklist rendering in `internal/board/card.go` and `internal/board/detail.go`.
|
|
27
|
+
- Router priority marker support across board model/card/detail rendering.
|
|
28
|
+
- Task checklist state parsing in `internal/data/parser.go` and `internal/data/task.go`.
|
|
29
|
+
- File watcher auto-refresh and task status disk persistence in `internal/board/watch.go`, `internal/board/board.go`, `internal/board/model.go`, and `internal/board/update.go`.
|
|
30
|
+
|
|
31
|
+
## Task Files Reviewed
|
|
32
|
+
|
|
33
|
+
- `.savepoint/releases/v1/epics/E06-atari-noir-layout/tasks/T001-color-system.md`
|
|
34
|
+
- `.savepoint/releases/v1/epics/E06-atari-noir-layout/tasks/T002-header-and-dividers.md`
|
|
35
|
+
- `.savepoint/releases/v1/epics/E06-atari-noir-layout/tasks/T003-footer-status-bar.md`
|
|
36
|
+
- `.savepoint/releases/v1/epics/E06-atari-noir-layout/tasks/T004-component-refinement.md`
|
|
37
|
+
- `.savepoint/releases/v1/epics/E06-atari-noir-layout/tasks/T005-restore-nav-hints.md`
|
|
38
|
+
- `.savepoint/releases/v1/epics/E06-atari-noir-layout/tasks/T007-detail-card-fixes.md`
|
|
39
|
+
- `.savepoint/releases/v1/epics/E06-atari-noir-layout/tasks/T008-checkbox-states.md`
|
|
40
|
+
- `.savepoint/releases/v1/epics/E06-atari-noir-layout/tasks/T009-router-priority-marker.md`
|
|
41
|
+
- `.savepoint/releases/v1/epics/E06-atari-noir-layout/tasks/T010-auto-refresh-watcher.md`
|
|
42
|
+
|
|
43
|
+
## Changed Files In Epic Scope
|
|
44
|
+
|
|
45
|
+
- `go.mod`
|
|
46
|
+
- `go.sum`
|
|
47
|
+
- `internal/board/board.go`
|
|
48
|
+
- `internal/board/card.go`
|
|
49
|
+
- `internal/board/card_test.go`
|
|
50
|
+
- `internal/board/column.go`
|
|
51
|
+
- `internal/board/column_test.go`
|
|
52
|
+
- `internal/board/detail.go`
|
|
53
|
+
- `internal/board/detail_test.go`
|
|
54
|
+
- `internal/board/epic_panel.go`
|
|
55
|
+
- `internal/board/layout.go`
|
|
56
|
+
- `internal/board/model.go`
|
|
57
|
+
- `internal/board/update.go`
|
|
58
|
+
- `internal/board/view.go`
|
|
59
|
+
- `internal/board/view_test.go`
|
|
60
|
+
- `internal/board/watch.go`
|
|
61
|
+
- `internal/data/parser.go`
|
|
62
|
+
- `internal/data/parser_test.go`
|
|
63
|
+
- `internal/data/task.go`
|
|
64
|
+
- `internal/data/write.go`
|
|
65
|
+
- `internal/styles/palette.go`
|
|
66
|
+
- `internal/styles/styles.go`
|
|
67
|
+
|
|
68
|
+
## Drift Notes Found
|
|
69
|
+
|
|
70
|
+
- `T002-header-and-dividers.md`: `internal/styles/palette.go` and `internal/styles/styles.go` were not yet reflected with sufficient specificity in the Codebase Map.
|
|
71
|
+
|
|
72
|
+
## Verification
|
|
73
|
+
|
|
74
|
+
- `go build ./...`: PASS
|
|
75
|
+
- `go test ./...`: PASS
|
|
76
|
+
- Approval closeout rerun: `go build ./...` PASS, `go test ./...` PASS.
|
|
77
|
+
- `make build` and `make test`: not run; `make` is not installed on PATH in this environment.
|
|
78
|
+
|
|
79
|
+
## Audit Observations
|
|
80
|
+
|
|
81
|
+
- `agent-skills/audit/SKILL.md` is referenced by the root instructions but does not exist; `agent-skills/savepoint-audit/SKILL.md` was used as the equivalent audit skill.
|
|
82
|
+
- The epic Design title says `Epic E07`; the folder, router, and task IDs identify this epic as `E06-atari-noir-layout`.
|
|
83
|
+
- The implementation added scoped behavior beyond the original visual uplift: footer navigation hints, detail overlay spacing, card word-wrap, checklist state parsing/rendering, router priority markers, and fsnotify auto-refresh.
|
|
84
|
+
- Visual ACs around explicit full-width dividers and border reduction are not fully represented in `internal/board/view.go` and `internal/styles/styles.go`; see proposals quality review.
|
package/.savepoint/config.yml
CHANGED
|
@@ -13,9 +13,9 @@ audit:
|
|
|
13
13
|
divergence_threshold: 0.5 # warn if a proposal changes >50% of a live file
|
|
14
14
|
|
|
15
15
|
theme:
|
|
16
|
-
bg: "#
|
|
17
|
-
surface: "#
|
|
18
|
-
surface_2: "#
|
|
16
|
+
bg: "#000000"
|
|
17
|
+
surface: "#000000"
|
|
18
|
+
surface_2: "#000000"
|
|
19
19
|
border: "#1A1A1A"
|
|
20
20
|
text: "#F0E6DA"
|
|
21
21
|
accents:
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
---
|
|
2
2
|
type: epic-design
|
|
3
|
-
status:
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Epic
|
|
3
|
+
status: audited
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Epic E06: Atari-Noir Layout Uplift
|
|
7
7
|
|
|
8
8
|
## Purpose
|
|
9
9
|
|
|
@@ -38,5 +38,23 @@ Update the existing TUI to align with the **Atari-Noir SavePoint design system**
|
|
|
38
38
|
| `internal/board/view.go` | Implement header, footer, dividers |
|
|
39
39
|
| `internal/board/layout.go` | Adjust layout height calculations |
|
|
40
40
|
| `internal/board/column.go` | Refine column styling and spacing |
|
|
41
|
-
| `internal/board/card.go` | Refine card surface and focus state |
|
|
42
|
-
| `internal/board/epic_panel.go` | Refine epic panel layout |
|
|
41
|
+
| `internal/board/card.go` | Refine card surface and focus state |
|
|
42
|
+
| `internal/board/epic_panel.go` | Refine epic panel layout |
|
|
43
|
+
|
|
44
|
+
## Implemented As
|
|
45
|
+
|
|
46
|
+
- `internal/styles/palette.go` defines the Atari-Noir hex palette plus ANSI256/ANSI16 fallbacks.
|
|
47
|
+
- `internal/styles/styles.go` centralizes header, divider, footer, column, card, detail, glyph, and semantic tag styles.
|
|
48
|
+
- `internal/board/view.go` renders the static SavePoint header, explicit full-width top/bottom dividers, the static `PLAN │ BUILD │ AUDIT` footer, subdued navigation hints, and overlay composition.
|
|
49
|
+
- `internal/board/card.go` wraps long task titles instead of truncating them and uses a green `▣` marker for the router-priority task.
|
|
50
|
+
- `internal/board/detail.go` adds spacing below Acceptance Criteria and Implementation Plan headings, renders checklist state with `☑`/`□`, and labels the router-priority task.
|
|
51
|
+
- `internal/data/task.go` and `internal/data/parser.go` represent Implementation Plan items as `CheckItem{Text, Done}` and parse `- [x]`, `- [ ]`, and legacy `- ` items.
|
|
52
|
+
- `internal/data/write.go` persists task status and phase changes with mtime conflict protection.
|
|
53
|
+
- `internal/board/watch.go` adds fsnotify-based recursive release directory watching, 100ms debounce, and reload messages used by `internal/board/update.go`.
|
|
54
|
+
|
|
55
|
+
## Implementation Deltas
|
|
56
|
+
|
|
57
|
+
- The original visual-only scope expanded to include board usability fixes requested during E06: footer navigation hints, detail overlay spacing, card title word-wrap, checklist state rendering, router priority markers, and auto-refresh on task file changes.
|
|
58
|
+
- Audit closeout removed unnecessary borders from unfocused header, board, column, card, and epic-panel surfaces while preserving Atari Orange borders for focused cards/columns and detail overlays.
|
|
59
|
+
- User-approved visual guardrail: Background, Surface, and Surface 2 are intentionally the same black value in the terminal TUI. Do not reintroduce subtly different background fills for panels/cards.
|
|
60
|
+
- The main view now renders explicit full-width divider lines with `styles.Divider` rather than relying on component frames as separators.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
id: E06-atari-noir-layout/T007-detail-card-fixes
|
|
3
|
-
status:
|
|
3
|
+
status: done
|
|
4
4
|
objective: "Add line breaks under Acceptance Criteria and Implementation Plan headings in task detail, and word-wrap card titles instead of truncating"
|
|
5
5
|
depends_on: []
|
|
6
6
|
---
|
|
@@ -18,11 +18,11 @@ depends_on: []
|
|
|
18
18
|
|
|
19
19
|
## Implementation Plan
|
|
20
20
|
|
|
21
|
-
- [
|
|
22
|
-
- [
|
|
23
|
-
- [
|
|
24
|
-
- [
|
|
25
|
-
- [
|
|
21
|
+
- [x] Edit `internal/board/detail.go` — add `""` entry after the `Acceptance Criteria:` heading line and after the `Implementation Plan:` heading line.
|
|
22
|
+
- [x] Edit `internal/board/detail.go` — make `wrapText` and `splitLongWord` exported (capitalize) so they can be reused from `card.go`.
|
|
23
|
+
- [x] Edit `internal/board/card.go` — replace `truncate(t.Title, inner)` with a multi-line approach that word-wraps the title across available width.
|
|
24
|
+
- [x] Edit `internal/board/card.go` — combine wrapped title lines with newlines in the card content (joining with `\n`).
|
|
25
|
+
- [x] Run `make build && make test` to verify no regressions.
|
|
26
26
|
|
|
27
27
|
## Context Log
|
|
28
28
|
|
|
@@ -33,4 +33,4 @@ Files read:
|
|
|
33
33
|
|
|
34
34
|
Estimated input tokens: 600
|
|
35
35
|
|
|
36
|
-
Notes:
|
|
36
|
+
Notes: Exported WrapText/SplitLongWord from detail.go; updated card_test.go TestRenderCard_titleTruncated → TestRenderCard_titleWraps. Build and tests pass.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
id: E06-atari-noir-layout/T008-checkbox-states
|
|
3
|
-
status:
|
|
3
|
+
status: done
|
|
4
4
|
objective: "Parse and render checked/unchecked state for Implementation Plan checklist items"
|
|
5
5
|
depends_on: []
|
|
6
6
|
---
|
|
@@ -19,11 +19,11 @@ depends_on: []
|
|
|
19
19
|
|
|
20
20
|
## Implementation Plan
|
|
21
21
|
|
|
22
|
-
- [
|
|
23
|
-
- [
|
|
24
|
-
- [
|
|
25
|
-
- [
|
|
26
|
-
- [
|
|
22
|
+
- [x] Edit `internal/data/task.go` — add `CheckItem` struct with `Text string` and `Done bool` fields; change `Checklist []string` to `Checklist []CheckItem`.
|
|
23
|
+
- [x] Edit `internal/data/parser.go` — update `extractChecklistSection()` to detect `- [x] ` vs `- [ ] ` vs `- ` prefixes and set `Done` accordingly; strip prefix from `Text`.
|
|
24
|
+
- [x] Update all usages of `Checklist` across the codebase (likely only `board/detail.go` and tests).
|
|
25
|
+
- [x] Edit `internal/board/detail.go` — in the Implementation Plan section, render done items with `☑ ` + green `TagDone` styling and undone items with `□ ` + dim `CardMeta` styling.
|
|
26
|
+
- [x] Run `make build && make test` to verify no regressions.
|
|
27
27
|
|
|
28
28
|
## Context Log
|
|
29
29
|
|
|
@@ -32,7 +32,9 @@ Files read:
|
|
|
32
32
|
- `internal/data/parser.go`
|
|
33
33
|
- `internal/board/detail.go`
|
|
34
34
|
- `internal/styles/styles.go`
|
|
35
|
+
- `internal/data/parser_test.go`
|
|
36
|
+
- `internal/board/detail_test.go`
|
|
35
37
|
|
|
36
|
-
Estimated input tokens:
|
|
38
|
+
Estimated input tokens: 1200
|
|
37
39
|
|
|
38
|
-
Notes:
|
|
40
|
+
Notes: Added `extractChecklistItems` alongside existing `extractChecklistSection` (kept for `[]string` Acceptance path). Build and all tests pass.
|
package/.savepoint/releases/v1/epics/E06-atari-noir-layout/tasks/T009-router-priority-marker.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
id: E06-atari-noir-layout/T009-router-priority-marker
|
|
3
|
-
status:
|
|
3
|
+
status: done
|
|
4
4
|
objective: "Highlight the router priority task with a green marker on the card and optional text highlight"
|
|
5
5
|
depends_on: []
|
|
6
6
|
---
|
|
@@ -12,18 +12,19 @@ depends_on: []
|
|
|
12
12
|
- The model reads `RouterState.Task` (the `task:` field from `router.md`) and stores it as `Model.RouterTask`
|
|
13
13
|
- In the board view, the task card whose ID matches `RouterTask` shows a green `▣` glyph (using `TagDone`/green style) instead of the normal phase-colored glyph
|
|
14
14
|
- Non-priority tasks keep their existing phase-colored glyphs unchanged
|
|
15
|
+
- Board always default view to current state release and epic
|
|
15
16
|
- The task detail overlay shows a `"(router priority)"` label or marker when the displayed task matches `RouterTask`
|
|
16
17
|
- All existing keyboard interactions, column rendering, and card behavior remain intact
|
|
17
18
|
|
|
18
19
|
## Implementation Plan
|
|
19
20
|
|
|
20
|
-
- [
|
|
21
|
-
- [
|
|
22
|
-
- [
|
|
23
|
-
- [
|
|
24
|
-
- [
|
|
25
|
-
- [
|
|
26
|
-
- [
|
|
21
|
+
- [x] Edit `internal/board/model.go` — add `RouterTask string` field to `Model`.
|
|
22
|
+
- [x] Edit `internal/board/board.go` — in `newProjectModel()`, read `routerState.Task` into `model.RouterTask`.
|
|
23
|
+
- [x] Edit `internal/board/card.go` — update `RenderCard` to accept a `routerTaskID string` parameter; when `t.ID == routerTaskID`, replace the phase glyph with a green `▣` using `TagDone` style.
|
|
24
|
+
- [x] Edit `internal/board/card.go` — update `RenderCard` signature and callsites (`column.go`, `view.go`).
|
|
25
|
+
- [x] Edit `internal/board/detail.go` — update `RenderDetail` to accept a `routerTaskID string`; when matching, append a `"(router priority)"` green label line.
|
|
26
|
+
- [x] Update all callsites of `RenderCard` and `RenderDetail` to pass `m.RouterTask`.
|
|
27
|
+
- [x] Run `make build && make test` to verify no regressions.
|
|
27
28
|
|
|
28
29
|
## Context Log
|
|
29
30
|
|
|
@@ -35,7 +36,13 @@ Files read:
|
|
|
35
36
|
- `internal/board/detail.go`
|
|
36
37
|
- `internal/data/router.go`
|
|
37
38
|
- `internal/board/view.go`
|
|
39
|
+
- `internal/board/card_test.go`
|
|
40
|
+
- `internal/board/detail_test.go`
|
|
41
|
+
- `internal/board/column_test.go`
|
|
38
42
|
|
|
39
|
-
Estimated input tokens:
|
|
43
|
+
Estimated input tokens: 1800
|
|
40
44
|
|
|
41
45
|
Notes:
|
|
46
|
+
- `go build && go test ./...` — PASS (all board tests green)
|
|
47
|
+
- `RenderColumn` signature extended with `routerTaskID string`; all 7 test callsites updated
|
|
48
|
+
- New tests: `TestRenderCard_routerPriorityUsesGreenGlyph`, `TestRenderDetail_routerPriorityLabel`, `TestRenderDetail_noRouterPriorityLabelWhenNoMatch`
|
package/.savepoint/releases/v1/epics/E06-atari-noir-layout/tasks/T010-auto-refresh-watcher.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
id: E06-atari-noir-layout/T010-auto-refresh-watcher
|
|
3
|
-
status:
|
|
3
|
+
status: done
|
|
4
4
|
objective: "Auto-refresh the board when task files change on disk via fsnotify file watcher"
|
|
5
5
|
depends_on: []
|
|
6
6
|
---
|
|
@@ -19,26 +19,26 @@ depends_on: []
|
|
|
19
19
|
|
|
20
20
|
## Implementation Plan
|
|
21
21
|
|
|
22
|
-
- [
|
|
23
|
-
- [
|
|
22
|
+
- [x] Add `github.com/fsnotify/fsnotify` to `go.mod`
|
|
23
|
+
- [x] Create `internal/board/watch.go`:
|
|
24
24
|
- Define `fileChangeMsg struct{}` and `reloadMsg struct{ tasks []data.Task }`
|
|
25
25
|
- `watchFiles(w *fsnotify.Watcher) tea.Cmd` — blocks on watcher.Events, drains channel for 100ms, emits single `fileChangeMsg`
|
|
26
26
|
- `reloadTasks(root string) tea.Cmd` — calls `loadAllTasks(root)` and emits `reloadMsg{tasks}`
|
|
27
27
|
- `loadAllTasks(root string) ([]data.Task, error)` — extracted from `board.go`, reuses `Discover` + `Parser`
|
|
28
|
-
- [
|
|
29
|
-
- Add `
|
|
30
|
-
- `Init()` —
|
|
31
|
-
|
|
32
|
-
- [ ] Edit `internal/board/board.go`:
|
|
28
|
+
- [x] Edit `internal/board/model.go`:
|
|
29
|
+
- Add `Watcher *fsnotify.Watcher` field to `Model`
|
|
30
|
+
- `Init()` — returns `watchFiles(m.Watcher)` if watcher non-nil, else nil
|
|
31
|
+
- [x] Edit `internal/board/board.go`:
|
|
33
32
|
- Extract task-discovery loop from `newProjectModel` into `loadAllTasks(root string) ([]data.Task, error)`
|
|
34
|
-
- `newProjectModel` calls `loadAllTasks`
|
|
35
|
-
-
|
|
33
|
+
- `newProjectModel` calls `loadAllTasks` + `newWatcher`, sets `model.Watcher`
|
|
34
|
+
- `loadEpicTasks` now sets `task.Path` and `task.Mtime` from stat
|
|
35
|
+
- [x] Edit `internal/board/update.go`:
|
|
36
36
|
- Handle `fileChangeMsg` → return `reloadTasks(m.Root)` cmd
|
|
37
|
-
- Handle `reloadMsg` → swap `m.AllTasks = msg.tasks`, call `m.refreshTasks()`, return `watchFiles(m.
|
|
38
|
-
- On quit (`q`/`ctrl+c`), close `m.
|
|
39
|
-
-
|
|
40
|
-
|
|
41
|
-
- [
|
|
37
|
+
- Handle `reloadMsg` → swap `m.AllTasks = msg.tasks`, call `m.refreshTasks()`, return `watchFiles(m.Watcher)` to re-subscribe
|
|
38
|
+
- On quit (`q`/`ctrl+c`), close `m.Watcher` before `tea.Quit`
|
|
39
|
+
- `space`/`backspace` now call `data.WriteTaskStatus` to persist to disk
|
|
40
|
+
- [x] `internal/data/task.go`: added `Path string` and `Mtime time.Time` (yaml:"-") to Task
|
|
41
|
+
- [x] Run `go build ./...` and `go test ./...` to verify no regressions
|
|
42
42
|
|
|
43
43
|
## Context Log
|
|
44
44
|
|
|
@@ -47,15 +47,18 @@ Files read:
|
|
|
47
47
|
- `internal/board/board.go`
|
|
48
48
|
- `internal/board/update.go`
|
|
49
49
|
- `internal/board/transitions.go`
|
|
50
|
-
- `internal/board/watch.go` (
|
|
50
|
+
- `internal/board/watch.go` (created)
|
|
51
51
|
- `internal/data/write.go`
|
|
52
|
+
- `internal/data/task.go`
|
|
53
|
+
- `internal/data/parser.go`
|
|
52
54
|
- `.savepoint/AGENTS.md`
|
|
53
|
-
- `.savepoint/releases/v1/epics/E06-atari-noir-layout/Design.md`
|
|
54
|
-
- `.savepoint/releases/v1/epics/E06-atari-noir-layout/tasks/T009-router-priority-marker.md`
|
|
55
55
|
|
|
56
|
-
Estimated input tokens:
|
|
56
|
+
Estimated input tokens: 2200
|
|
57
|
+
|
|
58
|
+
Quality gates: `go build ./...` PASS, `go test ./...` PASS (board: 0.317s, data: 0.343s)
|
|
57
59
|
|
|
58
60
|
Notes:
|
|
59
|
-
-
|
|
60
|
-
-
|
|
61
|
-
-
|
|
61
|
+
- fsnotify v1.10.0 has no recursive AddWith option; used `filepath.WalkDir` + `w.Add` per subdir instead.
|
|
62
|
+
- `data.Task` gained `Path` and `Mtime` (yaml:"-") fields populated in `loadEpicTasks`.
|
|
63
|
+
- Advance/Retreat disk writes live in `update.go`, not `transitions.go` (keeps transitions pure).
|
|
64
|
+
- Watcher created in `newProjectModel`; Init() subscribes if non-nil; nil watcher = test-safe.
|
|
@@ -14,13 +14,19 @@ Performance, layout robustness, and structural improvements for the board TUI. F
|
|
|
14
14
|
- Right-border clipping is eliminated at all terminal widths ≥ 40
|
|
15
15
|
- Resize handling is robust — no corruption, no artifacts when growing/shrinking
|
|
16
16
|
- The board auto-refreshes when task files change on disk via fsnotify
|
|
17
|
+
- Board columns use virtual viewport scrolling — 4-5 cards visible with `↑/↓` indicators
|
|
18
|
+
- Detail overlay is height-capped (~70%) with scroll indicators for overflow content
|
|
19
|
+
- All scroll indicators use dim/subtle styling consistent with Atari Noir aesthetic
|
|
17
20
|
|
|
18
21
|
## Components and files
|
|
19
22
|
|
|
20
23
|
| Path | Purpose |
|
|
21
24
|
|------|---------|
|
|
22
|
-
| `internal/board/layout.go` | Layout arithmetic and resize guards |
|
|
23
|
-
| `internal/board/view.go` | Minimum width clamping |
|
|
25
|
+
| `internal/board/layout.go` | Layout arithmetic and resize guards, height-aware ContentHeight |
|
|
26
|
+
| `internal/board/view.go` | Minimum width clamping, height passthrough to renderers |
|
|
24
27
|
| `internal/board/watch.go` | File watcher and reload commands |
|
|
25
|
-
| `internal/board/model.go` | Watcher lifecycle |
|
|
26
|
-
| `internal/board/update.go` | Reload message handling |
|
|
28
|
+
| `internal/board/model.go` | Watcher lifecycle, ColumnOffsets, DetailOffset state |
|
|
29
|
+
| `internal/board/update.go` | Reload message handling, auto-scroll offsets, PageUp/PageDown |
|
|
30
|
+
| `internal/board/column.go` | Virtual viewport slicing, scroll indicator rendering |
|
|
31
|
+
| `internal/board/detail.go` | Height-capped overlay, detail scroll indicators |
|
|
32
|
+
| `internal/styles/styles.go` | ScrollIndicator style (dim/subtle) |
|
package/.savepoint/releases/v1.1/epics/E01-tui-optimisation/tasks/T002-rename-epic-design-files.md
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: E01-tui-optimisation/T002-rename-epic-design-files
|
|
3
|
+
status: planned
|
|
4
|
+
objective: "Rename all epic Design.md files to E##-Detail.md convention"
|
|
5
|
+
depends_on: []
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# T002: Rename Epic Design Files
|
|
9
|
+
|
|
10
|
+
## Acceptance Criteria
|
|
11
|
+
|
|
12
|
+
- All 8 active epic `Design.md` files renamed to `E##-Detail.md` pattern
|
|
13
|
+
- Archived epics under `_archived/` left unchanged
|
|
14
|
+
- Root `.savepoint/Design.md` left unchanged
|
|
15
|
+
- No content changes in renamed files
|
|
16
|
+
- All renamed files remain valid markdown with intact frontmatter
|
|
17
|
+
|
|
18
|
+
## Implementation Plan
|
|
19
|
+
|
|
20
|
+
- [ ] Rename `.savepoint/releases/v1/epics/E01-scaffolding/Design.md` → `E01-Detail.md`
|
|
21
|
+
- [ ] Rename `.savepoint/releases/v1/epics/E02-architecture/Design.md` → `E02-Detail.md`
|
|
22
|
+
- [ ] Rename `.savepoint/releases/v1/epics/E03-board-tui-core/Design.md` → `E03-Detail.md`
|
|
23
|
+
- [ ] Rename `.savepoint/releases/v1/epics/E04-board-components/Design.md` → `E04-Detail.md`
|
|
24
|
+
- [ ] Rename `.savepoint/releases/v1/epics/E05-phase-transitions/Design.md` → `E05-Detail.md`
|
|
25
|
+
- [ ] Rename `.savepoint/releases/v1/epics/E06-atari-noir-layout/Design.md` → `E06-Detail.md`
|
|
26
|
+
- [ ] Rename `.savepoint/releases/v1.1/epics/E01-tui-optimisation/Design.md` → `E01-Detail.md`
|
|
27
|
+
- [ ] Rename `.savepoint/releases/v1.1/epics/E02-cross-platform-compatibility/Design.md` → `E02-Detail.md`
|
|
28
|
+
|
|
29
|
+
## Context Log
|
|
30
|
+
|
|
31
|
+
Files read:
|
|
32
|
+
- None (file renames only)
|
|
33
|
+
|
|
34
|
+
Estimated input tokens: 300
|
|
35
|
+
|
|
36
|
+
Notes:
|
|
37
|
+
- Content is not modified, only file paths change
|
|
38
|
+
- Archived epics explicitly excluded per user request
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: E01-tui-optimisation/T003-rename-release-prd
|
|
3
|
+
status: planned
|
|
4
|
+
objective: "Rename release PRD.md to version-anchored convention"
|
|
5
|
+
depends_on: []
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# T003: Rename Release PRD
|
|
9
|
+
|
|
10
|
+
## Acceptance Criteria
|
|
11
|
+
|
|
12
|
+
- `.savepoint/releases/v1/PRD.md` renamed to `.savepoint/releases/v1/v1-PRD.md`
|
|
13
|
+
- No content changes
|
|
14
|
+
- Root `.savepoint/PRD.md` left unchanged
|
|
15
|
+
|
|
16
|
+
## Implementation Plan
|
|
17
|
+
|
|
18
|
+
- [ ] Rename `.savepoint/releases/v1/PRD.md` → `v1-PRD.md`
|
|
19
|
+
|
|
20
|
+
## Context Log
|
|
21
|
+
|
|
22
|
+
Files read:
|
|
23
|
+
- None (file rename only)
|
|
24
|
+
|
|
25
|
+
Estimated input tokens: 100
|
|
26
|
+
|
|
27
|
+
Notes:
|
|
28
|
+
- Single file rename
|