appendPromptHistory writes value as one more entry, trimming to historyMaxEntries to bound growth. Empty prompts are skipped so stray ↵ presses don't pollute recall; entries over historyMaxEntryBytes are dropped (recall would fail at the scanner cap anyway). O_APPEND so two codehamr processes in th
(dir, value string)
| 62 | // best-effort: an IO error during rewrite leaves the appended file as-is. |
| 63 | // The next start trims it back down. |
| 64 | func appendPromptHistory(dir, value string) error { |
| 65 | if value == "" { |
| 66 | return nil |
| 67 | } |
| 68 | if len(value) > historyMaxEntryBytes { |
| 69 | return nil |
| 70 | } |
| 71 | // Quote expands control/invalid bytes to \xNN (4× each), so a value under |
| 72 | // the unquoted cap can still quote past historyScannerMax, and such a line |
| 73 | // halts the scan, losing every newer entry. Decline to store what the |
| 74 | // loader can't read back. (bufio needs the token strictly below the buffer |
| 75 | // max, hence >=.) |
| 76 | quoted := strconv.Quote(value) |
| 77 | if len(quoted) >= historyScannerMax { |
| 78 | return nil |
| 79 | } |
| 80 | line := quoted + "\n" |
| 81 | path := historyPath(dir) |
| 82 | f, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0o600) |
| 83 | if err != nil { |
| 84 | return err |
| 85 | } |
| 86 | if _, err := f.WriteString(line); err != nil { |
| 87 | _ = f.Close() |
| 88 | return err |
| 89 | } |
| 90 | if err := f.Close(); err != nil { |
| 91 | return err |
| 92 | } |
| 93 | // Lazy trim: rewrite only once the count exceeds historyMaxEntries. |
| 94 | count, err := countHistoryLines(path) |
| 95 | if err != nil || count <= historyMaxEntries { |
| 96 | return nil |
| 97 | } |
| 98 | all := loadPromptHistory(dir) |
| 99 | if len(all) > historyMaxEntries { |
| 100 | all = all[len(all)-historyMaxEntries:] |
| 101 | } |
| 102 | var buf []byte |
| 103 | for _, e := range all { |
| 104 | buf = append(buf, strconv.Quote(e.display)...) |
| 105 | buf = append(buf, '\n') |
| 106 | } |
| 107 | // Best-effort: a failure keeps the over-cap-but-correct file rather than |
| 108 | // reporting an error that would obscure the successful append above. |
| 109 | _ = os.WriteFile(path, buf, 0o600) |
| 110 | return nil |
| 111 | } |
| 112 | |
| 113 | // countHistoryLines tallies lines without parsing them: fast path for the |
| 114 | // trim decision in appendPromptHistory. |