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.
Files changed (49) hide show
  1. package/.claude/settings.local.json +5 -1
  2. package/.savepoint/Design.md +8 -4
  3. package/.savepoint/audit/E06-atari-noir-layout/proposals.md +130 -0
  4. package/.savepoint/audit/E06-atari-noir-layout/snapshot.md +84 -0
  5. package/.savepoint/config.yml +3 -3
  6. package/.savepoint/releases/v1/epics/E06-atari-noir-layout/Design.md +24 -6
  7. package/.savepoint/releases/v1/epics/E06-atari-noir-layout/tasks/T007-detail-card-fixes.md +7 -7
  8. package/.savepoint/releases/v1/epics/E06-atari-noir-layout/tasks/T008-checkbox-states.md +10 -8
  9. package/.savepoint/releases/v1/epics/E06-atari-noir-layout/tasks/T009-router-priority-marker.md +16 -9
  10. package/.savepoint/releases/v1/epics/E06-atari-noir-layout/tasks/T010-auto-refresh-watcher.md +25 -22
  11. package/.savepoint/releases/v1.1/epics/E01-tui-optimisation/Design.md +10 -4
  12. package/.savepoint/releases/v1.1/epics/E01-tui-optimisation/tasks/T001-border-resize-fix.md +2 -1
  13. package/.savepoint/releases/v1.1/epics/E01-tui-optimisation/tasks/T002-rename-epic-design-files.md +38 -0
  14. package/.savepoint/releases/v1.1/epics/E01-tui-optimisation/tasks/T003-rename-release-prd.md +28 -0
  15. package/.savepoint/releases/v1.1/epics/E01-tui-optimisation/tasks/T004-update-instruction-files.md +50 -0
  16. package/.savepoint/releases/v1.1/epics/E01-tui-optimisation/tasks/T005-update-cross-references.md +44 -0
  17. package/.savepoint/releases/v1.1/epics/E01-tui-optimisation/tasks/T006-column-and-detail-scrolling.md +58 -0
  18. package/.savepoint/releases/v1.1/epics/E01-tui-optimisation/tasks/T007-next-activity-header.md +55 -0
  19. package/.savepoint/releases/v1.1/epics/E02-cross-platform-compatibility/Design.md +40 -0
  20. package/.savepoint/releases/v1.1/epics/E02-cross-platform-compatibility/tasks/T001-fix-makefile.md +34 -0
  21. package/.savepoint/releases/v1.1/epics/E02-cross-platform-compatibility/tasks/T002-linux-build-target.md +33 -0
  22. package/.savepoint/releases/v1.1/epics/E02-cross-platform-compatibility/tasks/T003-macos-build-target.md +32 -0
  23. package/.savepoint/releases/v1.1/epics/E02-cross-platform-compatibility/tasks/T004-smoke-tests-and-artifacts.md +38 -0
  24. package/.savepoint/router.md +1 -1
  25. package/.savepoint/visual-identity.md +4 -3
  26. package/AGENTS.md +3 -3
  27. package/README.md +1 -1
  28. package/go.mod +4 -1
  29. package/go.sum +2 -0
  30. package/internal/board/board.go +42 -6
  31. package/internal/board/board_test.go +53 -0
  32. package/internal/board/card.go +9 -3
  33. package/internal/board/card_test.go +28 -14
  34. package/internal/board/column.go +2 -2
  35. package/internal/board/column_test.go +17 -9
  36. package/internal/board/detail.go +21 -11
  37. package/internal/board/detail_test.go +30 -14
  38. package/internal/board/model.go +7 -1
  39. package/internal/board/update.go +24 -1
  40. package/internal/board/view.go +13 -3
  41. package/internal/board/view_test.go +2 -2
  42. package/internal/board/watch.go +82 -0
  43. package/internal/data/parser.go +31 -1
  44. package/internal/data/parser_test.go +8 -2
  45. package/internal/data/task.go +12 -2
  46. package/internal/styles/palette.go +6 -4
  47. package/internal/styles/styles.go +5 -15
  48. package/package.json +5 -4
  49. package/savepoint +0 -0
@@ -51,7 +51,7 @@ func (p *Parser) ParseTaskFile(path string, content string) (*Task, error) {
51
51
  Points: fields.Points,
52
52
  Tags: fields.Tags,
53
53
  Acceptance: firstList(fields.Acceptance, extractChecklistSection(content, "## Acceptance Criteria")),
54
- Checklist: extractChecklistSection(content, "## Implementation Plan"),
54
+ Checklist: extractChecklistItems(content, "## Implementation Plan"),
55
55
  Notes: fields.Notes,
56
56
  DependsOn: fields.DependsOn,
57
57
  Progress: fields.Progress,
@@ -162,6 +162,36 @@ func firstList(values ...[]string) []string {
162
162
  return nil
163
163
  }
164
164
 
165
+ func extractChecklistItems(content, heading string) []CheckItem {
166
+ normalized := strings.ReplaceAll(content, "\r\n", "\n")
167
+ start := strings.Index(normalized, heading)
168
+ if start == -1 {
169
+ return nil
170
+ }
171
+
172
+ section := normalized[start+len(heading):]
173
+ if next := strings.Index(section, "\n## "); next != -1 {
174
+ section = section[:next]
175
+ }
176
+
177
+ items := []CheckItem{}
178
+ for _, line := range strings.Split(section, "\n") {
179
+ trimmed := strings.TrimSpace(line)
180
+ if strings.HasPrefix(trimmed, "- [x] ") {
181
+ items = append(items, CheckItem{Text: strings.TrimSpace(trimmed[6:]), Done: true})
182
+ continue
183
+ }
184
+ if strings.HasPrefix(trimmed, "- [ ] ") {
185
+ items = append(items, CheckItem{Text: strings.TrimSpace(trimmed[6:]), Done: false})
186
+ continue
187
+ }
188
+ if strings.HasPrefix(trimmed, "- ") {
189
+ items = append(items, CheckItem{Text: strings.TrimSpace(trimmed[2:]), Done: false})
190
+ }
191
+ }
192
+ return items
193
+ }
194
+
165
195
  func extractChecklistSection(content, heading string) []string {
166
196
  normalized := strings.ReplaceAll(content, "\r\n", "\n")
167
197
  start := strings.Index(normalized, heading)
@@ -210,7 +210,13 @@ Notes here.`
210
210
  if len(task.Acceptance) != 2 || task.Acceptance[0] != "First criterion." || task.Acceptance[1] != "Second criterion." {
211
211
  t.Errorf("Task.Acceptance = %v, want markdown criteria", task.Acceptance)
212
212
  }
213
- if len(task.Checklist) != 2 || task.Checklist[0] != "First checklist item." || task.Checklist[1] != "Second checklist item." {
214
- t.Errorf("Task.Checklist = %v, want markdown checklist", task.Checklist)
213
+ if len(task.Checklist) != 2 {
214
+ t.Fatalf("Task.Checklist len = %d, want 2", len(task.Checklist))
215
+ }
216
+ if task.Checklist[0].Text != "First checklist item." || task.Checklist[0].Done {
217
+ t.Errorf("Task.Checklist[0] = %+v, want {Text:\"First checklist item.\", Done:false}", task.Checklist[0])
218
+ }
219
+ if task.Checklist[1].Text != "Second checklist item." || !task.Checklist[1].Done {
220
+ t.Errorf("Task.Checklist[1] = %+v, want {Text:\"Second checklist item.\", Done:true}", task.Checklist[1])
215
221
  }
216
222
  }
@@ -1,6 +1,14 @@
1
1
  package data
2
2
 
3
- import "fmt"
3
+ import (
4
+ "fmt"
5
+ "time"
6
+ )
7
+
8
+ type CheckItem struct {
9
+ Text string
10
+ Done bool
11
+ }
4
12
 
5
13
  type ColumnType string
6
14
 
@@ -35,10 +43,12 @@ type Task struct {
35
43
  Points int `yaml:"points,omitempty"`
36
44
  Tags []string `yaml:"tags,omitempty"`
37
45
  Acceptance []string `yaml:"acceptance,omitempty"`
38
- Checklist []string `yaml:"checklist,omitempty"`
46
+ Checklist []CheckItem `yaml:"checklist,omitempty"`
39
47
  Notes string `yaml:"notes,omitempty"`
40
48
  DependsOn []string `yaml:"depends_on,omitempty"`
41
49
  Progress Progress `yaml:"progress,omitempty"`
50
+ Path string `yaml:"-"`
51
+ Mtime time.Time `yaml:"-"`
42
52
  }
43
53
 
44
54
  func (t Task) String() string {
@@ -1,10 +1,12 @@
1
1
  package styles
2
2
 
3
- // Truecolor hex constants (Atari-Noir palette)
3
+ // Truecolor hex constants (Atari-Noir palette).
4
+ // Background, Surface, and Surface2 intentionally share one black value so the
5
+ // terminal stays visually flat; hierarchy comes from spacing, dividers, and accents.
4
6
  const (
5
- Background = "#121212"
6
- Surface = "#0D0D0D"
7
- Surface2 = "#0F0F0F"
7
+ Background = "#000000"
8
+ Surface = "#000000"
9
+ Surface2 = "#000000"
8
10
  Border = "#1A1A1A"
9
11
  BorderSubtle = "#222222"
10
12
  PrimaryText = "#F0E6DA"
@@ -10,8 +10,8 @@ var (
10
10
  clrOrange = color(AtariOrange, AtariOrange256, AtariOrange16)
11
11
  clrText = color(PrimaryText, PrimaryText256, PrimaryText16)
12
12
  clrBorder = color(BorderSubtle, BorderSubtle256, BorderSubtle16)
13
- clrSurface = color(Surface2, Surface2256, Surface216) // #0F0F0F
14
- clrSurfaceDark = color(Surface, Surface256, Surface16) // #0D0D0D
13
+ clrSurface = color(Surface2, Surface2256, Surface216) // intentionally black
14
+ clrSurfaceDark = color(Surface, Surface256, Surface16) // intentionally black
15
15
  clrGreen = color(NPPGreen, NPPGreen256, NPPGreen16)
16
16
  clrPurple = color(VibePurple, VibePurple256, VibePurple16)
17
17
  clrDim = color(Dim, Dim256, Dim16)
@@ -29,18 +29,13 @@ var (
29
29
  Foreground(clrBorder)
30
30
 
31
31
  HeaderFrame = lipgloss.NewStyle().
32
- BorderStyle(lipgloss.RoundedBorder()).
33
- BorderForeground(clrBorder).
32
+ Background(clrSurfaceDark).
34
33
  Padding(1, 1)
35
34
 
36
35
  BoardFrame = lipgloss.NewStyle().
37
- BorderStyle(lipgloss.RoundedBorder()).
38
- BorderForeground(clrBorder).
39
- Padding(0, 1)
36
+ Background(clrSurfaceDark)
40
37
 
41
38
  Column = lipgloss.NewStyle().
42
- BorderStyle(lipgloss.RoundedBorder()).
43
- BorderForeground(clrBorder).
44
39
  Background(clrSurfaceDark).
45
40
  Padding(0, 1)
46
41
 
@@ -65,18 +60,13 @@ var (
65
60
  Foreground(clrOrange)
66
61
 
67
62
  StatusBar = lipgloss.NewStyle().
68
- Foreground(clrText).
69
- Background(clrSurface)
63
+ Foreground(clrText)
70
64
 
71
65
  EpicPanel = lipgloss.NewStyle().
72
- BorderStyle(lipgloss.RoundedBorder()).
73
- BorderForeground(clrPurple).
74
66
  Background(clrSurface).
75
67
  Padding(0, 1)
76
68
 
77
69
  Card = lipgloss.NewStyle().
78
- BorderStyle(lipgloss.RoundedBorder()).
79
- BorderForeground(clrBorder).
80
70
  Background(clrSurface).
81
71
  Padding(0, 1)
82
72
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "savepoint",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "It’s a simple, file-based state machine and cinematic Terminal UI (TUI) designed to force you—and your agent (Claude, Cursor, Aider, Gemini)—to slow down, write down what you're actually building, and check your work before moving on.",
5
5
  "keywords": [
6
6
  "board",
@@ -17,9 +17,10 @@
17
17
  },
18
18
  "license": "MIT",
19
19
  "author": "anipatke",
20
- "type": "Go",
21
- "main": "main.go",
20
+ "bin": {
21
+ "savepoint": "./savepoint"
22
+ },
22
23
  "scripts": {
23
24
  "test": "savepoint init"
24
25
  }
25
- }
26
+ }
package/savepoint CHANGED
Binary file