feat: add command history persistence (#152)

This PR adds a command history persistence feature to Codex CLI that:

1. **Stores command history**: Commands are saved to
`~/.codex/history.json` and persist between CLI sessions.
2. **Navigates history**: Users can use the up/down arrow keys to
navigate through command history, similar to a traditional shell.
3. **Filters sensitive data**: Built-in regex patterns prevent commands
containing API keys, passwords, or tokens from being saved.
4. **Configurable**: Added configuration options for history size,
enabling/disabling history, and custom regex patterns for sensitive
content.
5. **New command**: Added `/clearhistory` command to clear command
history.

  ## Code Changes

- Added `src/utils/storage/command-history.ts` with functions for
history management
  - Extended config system to support history settings
  - Updated terminal input components to use persistent history
  - Added help text for the new `/clearhistory` command
  - Added CLAUDE.md file for guidance when working with the codebase

  ## Testing

  - All tests are passing
- Core functionality works with both input components (standard and
multiline)
- History navigation behaves correctly at line boundaries with the
multiline editor
This commit is contained in:
Tomas Cupr
2025-04-17 21:41:54 +02:00
committed by GitHub
parent 5e1d149eb5
commit 295079cf33
6 changed files with 326 additions and 29 deletions

View File

@@ -58,10 +58,10 @@ test("loads default config if files don't exist", () => {
const config = loadConfig(testConfigPath, testInstructionsPath, {
disableProjectDoc: true,
});
expect(config).toEqual({
model: "o4-mini",
instructions: "",
});
// Keep the test focused on just checking that default model and instructions are loaded
// so we need to make sure we check just these properties
expect(config.model).toBe("o4-mini");
expect(config.instructions).toBe("");
});
test("saves and loads config correctly", () => {
@@ -78,7 +78,9 @@ test("saves and loads config correctly", () => {
const loadedConfig = loadConfig(testConfigPath, testInstructionsPath, {
disableProjectDoc: true,
});
expect(loadedConfig).toEqual(testConfig);
// Check just the specified properties that were saved
expect(loadedConfig.model).toBe(testConfig.model);
expect(loadedConfig.instructions).toBe(testConfig.instructions);
});
test("loads user instructions + project doc when codex.md is present", () => {