fix: replace all non-ASCII characters with safe ASCII equivalents

Replace box-drawing characters (U+2500) in session log with ASCII dashes.
Replace em dashes (U+2014) in CLAUDE.md template with double hyphens.
Remove em dash from comment in run.go.
Add ASCII-guard tests for session log output and seed templates.
Prevents mojibake on Windows terminals that misinterpret UTF-8 as CP1252.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-06 10:15:02 -04:00
parent f967064331
commit 75911faeeb
5 changed files with 60 additions and 11 deletions
+2 -2
View File
@@ -40,7 +40,7 @@ func FormatSessionEntry(info *SessionInfo) string {
duration := info.EndTime.Sub(info.StartTime)
timeFmt := "2006-01-02 15:04:05"
fmt.Fprintf(&b, "── Session %s ──\n", info.StartTime.Format(timeFmt))
fmt.Fprintf(&b, "-- Session %s --\n", info.StartTime.Format(timeFmt))
fmt.Fprintf(&b, "Agent: %s\n", info.Agent)
fmt.Fprintf(&b, "Mode: %s\n", info.Mode)
fmt.Fprintf(&b, "Start: %s\n", info.StartTime.Format(timeFmt))
@@ -96,7 +96,7 @@ func FormatSessionEntry(info *SessionInfo) string {
b.WriteString("(No changes detected)\n")
}
b.WriteString("────────────────────────────────\n")
b.WriteString("--------------------------------\n")
return b.String()
}
+26 -2
View File
@@ -127,8 +127,8 @@ func TestAppendSessionLog(t *testing.T) {
content := string(data)
// Should contain both sessions
if strings.Count(content, "── Session") != 2 {
t.Errorf("expected 2 session entries, got %d", strings.Count(content, "── Session"))
if strings.Count(content, "-- Session") != 2 {
t.Errorf("expected 2 session entries, got %d", strings.Count(content, "-- Session"))
}
}
@@ -167,3 +167,27 @@ func TestManifestCleanupOnSuccess(t *testing.T) {
t.Error("manifest should be cleaned up after successful logging")
}
}
func TestSessionLogIsASCII(t *testing.T) {
start := time.Date(2026, 4, 5, 14, 30, 22, 0, time.UTC)
end := time.Date(2026, 4, 5, 15, 45, 10, 0, time.UTC)
info := &SessionInfo{
Agent: "claude",
Mode: "local",
StartTime: start,
EndTime: end,
Diff: &ManifestDiff{
Added: []string{"output/result.md"},
Modified: []string{"notes.md"},
},
}
entry := FormatSessionEntry(info)
for i, b := range []byte(entry) {
if b > 127 {
t.Errorf("non-ASCII byte 0x%02x at position %d in session log output", b, i)
break
}
}
}
+1 -1
View File
@@ -33,7 +33,7 @@ func Run(opts LaunchOpts) error {
startManifest, err := CaptureManifest(opts.WsDir)
if err != nil {
fmt.Fprintf(os.Stderr, "[ctask] warning: failed to capture start manifest: %v\n", err)
// Continue anyway never block the user
// Continue anyway -- never block the user
}
if startManifest != nil {