Skip to content

Commit 515e832

Browse files
authored
Merge pull request #2 from seabearDEV/claude/verify-codexcli-readme-qVZ44
- Remove redundant resolveKey() call in editEntry (caller already resolves) - Add edit/e command and --json/-j flag to tab completions - Interpolate values in --json output mode for get command - Set process.exitCode=1 for not-found keys in JSON mode - Log debug warning instead of silently swallowing lock failures - Add TOCTOU mitigation comment on stale lock removal - Replace deprecated rmdirSync with rmSync - Replace dynamic imports with static fs/os/path imports in editEntry - Reset confirm keys when importing type=all without confirm key present - Always include searched sub-keys in JSON search output (even when empty) - Add comment explaining intentional undefined fallthrough in stdin path - Add backup rotation keeping only 10 most recent backups")
2 parents 943f0d2 + 1d156e9 commit 515e832

28 files changed

Lines changed: 1219 additions & 134 deletions

CHANGELOG.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,31 @@ All notable changes to this project will be documented in this file.
44

55
The format is based on [Keep a Changelog](https://keepachangelog.com/), and this project adheres to [Semantic Versioning](https://semver.org/).
66

7+
## [Unreleased]
8+
9+
### Added
10+
11+
- `edit` command (alias `e`) — open an entry's value in `$EDITOR` / `$VISUAL` with `--decrypt` support
12+
- `--json` / `-j` flag on `get` and `find` for machine-readable JSON output
13+
- Stdin piping for `set` — read value from stdin when piped (`echo "val" | ccli set key`)
14+
- `confirm` as a standalone type for `data export`, `data import`, and `data reset`
15+
- Advisory file locking (`fileLock.ts`) — all writes are lock-protected with stale-lock detection
16+
- Auto-backup before destructive operations (`data reset`, non-merge `data import`) in `~/.codexcli/.backups/`
17+
- MCP `codex_set`: `encrypt` and `password` parameters for encrypted storage
18+
- MCP `codex_get`: `decrypt` and `password` parameters for encrypted retrieval
19+
- MCP `codex_run`: `force` parameter to skip confirm check on protected entries
20+
- MCP `codex_export`, `codex_import`, `codex_reset`: support for `confirm` data type
21+
- Windows clipboard support via `clip` command
22+
23+
### Fixed
24+
25+
- `showExamples()` referenced non-existent flags `-k`, `-v`, `-e` — now uses valid flags
26+
- `showHelp()` config signature and subcommands were incorrect — now shows `<subcommand>` with correct list
27+
- `displayAliases` empty-state message referenced deleted command — now shows `set <key> <value> -a <alias>`
28+
- `data export all -o <file>` overwrote the same file three times — filenames now suffixed with type
29+
- MCP `codex_run` ignored `confirm` metadata — now checks confirm before executing
30+
- Data files used default permissions (0644) — now use 0600; directories use 0700
31+
732
## [0.1.0] - 2026-02-20
833

934
### Added

ISSUES.md

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
# CodexCLI — Known Issues & Missing Features
2+
3+
Comprehensive audit of bugs, inconsistencies, and missing features.
4+
5+
---
6+
7+
## P0 — Bugs (FIXED)
8+
9+
### 1. ~~`showExamples()` references non-existent flags `-k`, `-v`, `-e`~~ FIXED
10+
11+
**File:** `src/formatting.ts`
12+
13+
Examples now use valid flags: `get -a` (aliases only), `find prod -e` (entries only), `find ip -a` (aliases only), `find server -t` (tree).
14+
15+
### 2. ~~`showHelp()` config signature and subcommands are wrong~~ FIXED
16+
17+
**File:** `src/formatting.ts`
18+
19+
Config line now shows `<subcommand>` and SUBCOMMANDS section includes `set, get, info, examples, completions`.
20+
21+
### 3. ~~`displayAliases` empty-state message references deleted command~~ FIXED
22+
23+
**File:** `src/commands/helpers.ts`
24+
25+
Message now shows the correct command: `set <key> <value> -a <alias>`.
26+
27+
### 4. ~~`data export all -o <file>` overwrites same file three times~~ FIXED
28+
29+
**File:** `src/commands/data-management.ts`
30+
31+
When `type === 'all'` and `-o` is specified, filenames are suffixed with the type (e.g., `backup-entries.json`, `backup-aliases.json`, `backup-confirm.json`).
32+
33+
---
34+
35+
## P1 — Security & Platform Gaps (FIXED)
36+
37+
### 5. ~~MCP `codex_run` ignores `confirm` metadata~~ FIXED
38+
39+
**File:** `src/mcp-server.ts`
40+
41+
`codex_run` now imports `hasConfirm` and checks confirm metadata before executing. If an entry has confirm set and `force` is not `true` (and not a dry run), execution is refused with an error message. Added `force` parameter to the tool schema.
42+
43+
### 6. ~~Windows clipboard is unsupported~~ FIXED
44+
45+
**File:** `src/utils/clipboard.ts`
46+
47+
Added `win32` platform support using `clip` command.
48+
49+
### 7. ~~Data files use default permissions (0644)~~ FIXED
50+
51+
**File:** `src/utils/atomicWrite.ts`, `src/utils/paths.ts`, `src/commands/data-management.ts`
52+
53+
- `atomicWriteFileSync` now writes files with mode `0o600` (owner read/write only)
54+
- `ensureDataDirectoryExists` now creates directories with mode `0o700`
55+
- Export files in `data-management.ts` also use mode `0o600`
56+
57+
---
58+
59+
## P2 — Missing Core Features (FIXED)
60+
61+
### 8. ~~No stdin piping for `set`~~ FIXED
62+
63+
`set` now reads from stdin when piped (non-TTY): `echo "value" | ccli set key`.
64+
65+
### 9. ~~No `edit` command (`$EDITOR` support)~~ FIXED
66+
67+
Added `edit` (alias `e`) command: `ccli edit <key>` opens the value in `$EDITOR`/`$VISUAL`. Supports `--decrypt` for encrypted entries.
68+
69+
### 10. ~~MCP has no encryption support (set/get)~~ FIXED
70+
71+
`codex_set` now accepts `encrypt` and `password` parameters. `codex_get` now accepts `decrypt` and `password` parameters.
72+
73+
### 11. ~~`confirm` is not a standalone export/import type~~ FIXED
74+
75+
`confirm` is now a valid standalone type for `data export`, `data import`, and `data reset`. Also added to MCP `codex_export`, `codex_import`, and `codex_reset`.
76+
77+
### 12. ~~No file locking for concurrent access~~ FIXED
78+
79+
Added advisory file locking (`src/utils/fileLock.ts`) using `.lock` files with atomic `O_CREAT|O_EXCL`. Integrated into `saveJsonSorted` — all writes are now lock-protected. Stale locks (>10s) are automatically broken.
80+
81+
### 13. ~~No auto-backup before destructive operations~~ FIXED
82+
83+
Added `src/utils/autoBackup.ts`. Automatic backups are created in `~/.codexcli/.backups/` before `data reset` and non-merge `data import`.
84+
85+
### 14. ~~No `--json` output format~~ FIXED
86+
87+
Added `--json` / `-j` flag to `get` and `find` commands for machine-readable JSON output.
88+
89+
---
90+
91+
## P3 — Nice-to-Have Features
92+
93+
### 15. Fish/PowerShell shell completion
94+
95+
Only Bash and Zsh are supported. Fish and PowerShell users get no completions or wrapper.
96+
97+
### 16. No `copy`/`cp` command
98+
99+
Cannot duplicate an entry to a new key without get + set.
100+
101+
### 17. No import preview/diff
102+
103+
`data import --merge` silently overwrites conflicting keys with no way to preview what will change.
104+
105+
### 18. No advanced search (regex, boolean operators)
106+
107+
`find` only does case-insensitive substring matching. No regex, field-specific search, or boolean operators.
108+
109+
### 19. No backup rotation / automatic backup management
110+
111+
No built-in way to maintain a set of N recent backups.
112+
113+
### 20. No command output capture
114+
115+
`run` inherits stdio — no way to capture command output for chaining.
116+
117+
### 21. No change log / audit trail
118+
119+
No record of what was added, changed, or deleted over time.
120+
121+
### 22. No fuzzy finder integration
122+
123+
No `fzf` or similar interactive selection for keys.
124+
125+
### 23. No conditional interpolation
126+
127+
No `${ref:-default}` or `${ref:?error}` syntax for fallback values.
128+
129+
### 24. No batch operations
130+
131+
Cannot set multiple entries in one command.
132+
133+
---
134+
135+
## Summary
136+
137+
| Priority | Count | Description |
138+
|----------|-------|-------------|
139+
| **P0** | 4 | ~~Bugs showing incorrect info or causing data loss~~ ALL FIXED |
140+
| **P1** | 3 | ~~Security and platform gaps~~ ALL FIXED |
141+
| **P2** | 7 | ~~Missing core features~~ ALL FIXED |
142+
| **P3** | 10 | Nice-to-have features |

README.md

Lines changed: 53 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ A command-line information store for quick reference of frequently used data.
1414
- [Searching](#searching)
1515
- [Aliases](#aliases)
1616
- [Renaming](#renaming)
17+
- [Editing Data](#editing-data)
1718
- [Removing Data](#removing-data)
1819
- [Interpolation](#interpolation)
1920
- [Encryption](#encryption)
@@ -41,7 +42,12 @@ CodexCLI is a command-line tool designed to help you store, organize, and retrie
4142
- **Encryption**: Password-protect sensitive values
4243
- **Search**: Find entries by searching keys or values
4344
- **Tree Visualization**: Display nested data in a tree-like structure
44-
- **Clipboard Integration**: Copy values directly to clipboard
45+
- **Clipboard Integration**: Copy values directly to clipboard (macOS, Linux, Windows)
46+
- **Inline Editing**: Open entries in `$EDITOR` / `$VISUAL` for quick edits
47+
- **JSON Output**: Machine-readable `--json` flag on `get` and `find` for scripting
48+
- **Stdin Piping**: Pipe values into `set` from other commands
49+
- **Auto-Backup**: Automatic timestamped backups before destructive operations
50+
- **File Locking**: Advisory locking prevents data corruption from concurrent access
4551
- **Shell Tab-Completion**: Full tab-completion for Bash and Zsh (commands, flags, keys, aliases)
4652
- **MCP Server**: Expose CodexCLI as a tool for AI agents (Claude Code, Claude Desktop) via the Model Context Protocol
4753

@@ -84,6 +90,8 @@ ccli
8490

8591
### Install from Source
8692

93+
> **Note:** Installing from source registers the development binary `cclid` (not `ccli`). All examples in this README use `ccli`, but substitute `cclid` if you installed from source. The production `ccli` binary is available via Homebrew or the GitHub Releases download above.
94+
8795
Ensure npm's global binaries are in your PATH by adding the following to your shell profile (`.bashrc`, `.zshrc`, or equivalent):
8896

8997
```bash
@@ -98,7 +106,7 @@ npm run build
98106
npm install -g .
99107
```
100108

101-
If `ccli` is not found after installing, verify that npm's global bin directory is in your PATH:
109+
If `cclid` is not found after installing, verify that npm's global bin directory is in your PATH:
102110

103111
```bash
104112
echo $PATH | grep -o "$(npm config get prefix)/bin"
@@ -135,6 +143,12 @@ ccli set commands.deploy "./deploy.sh" --confirm
135143

136144
# Remove the confirmation requirement from an entry
137145
ccli set commands.deploy --no-confirm
146+
147+
# Pipe a value from stdin
148+
echo "my value" | ccli set mykey
149+
150+
# Pipe from another command
151+
curl -s https://api.example.com/token | ccli set api.token
138152
```
139153

140154
After setting an entry, you'll be asked interactively whether it should require confirmation to run. Use `--confirm` or `--no-confirm` to skip the prompt.
@@ -166,6 +180,9 @@ ccli get api.key -d
166180
# Copy value to clipboard
167181
ccli get server.ip -c
168182

183+
# Output as JSON (for scripting)
184+
ccli get server --json
185+
169186
# Show aliases only
170187
ccli get -a
171188
```
@@ -218,6 +235,9 @@ ccli find ip -a
218235

219236
# Show results as a tree
220237
ccli find server -t
238+
239+
# Output as JSON (for scripting)
240+
ccli find prod --json
221241
```
222242

223243
### Aliases
@@ -260,6 +280,18 @@ ccli rename -a oldalias newalias
260280
ccli rename server.old server.new --set-alias sn
261281
```
262282

283+
### Editing Data
284+
285+
Open a stored value in your `$EDITOR` (or `$VISUAL`) for inline editing:
286+
287+
```bash
288+
# Edit an entry in your default editor
289+
ccli edit server.production.ip
290+
291+
# Edit an encrypted entry (decrypts before editing, re-encrypts on save)
292+
ccli edit api.key --decrypt
293+
```
294+
263295
### Removing Data
264296

265297
Removing an entry prompts for confirmation. Use `-f` to skip.
@@ -359,8 +391,14 @@ ccli data export entries
359391
# Export to a specific file
360392
ccli data export aliases -o my-aliases.json
361393

362-
# Export everything
363-
ccli data export all -o backup.json
394+
# Export with pretty-printed JSON
395+
ccli data export entries --pretty
396+
397+
# Export confirm metadata
398+
ccli data export confirm
399+
400+
# Export everything (entries, aliases, confirm metadata)
401+
ccli data export all
364402

365403
# Import data from a file (replaces existing)
366404
ccli data import entries backup.json
@@ -375,6 +413,8 @@ ccli data reset entries
375413
ccli data reset all -f
376414
```
377415

416+
> **Auto-backup:** Before destructive operations (`data reset`, non-merge `data import`), CodexCLI automatically creates a timestamped backup in `~/.codexcli/.backups/`.
417+
378418
### Shell Wrapper
379419

380420
By default, `ccli run` executes commands in a child process. This means shell builtins like `cd`, `export`, and `alias` have no effect on your current shell.
@@ -432,7 +472,7 @@ eval "$(ccli config completions bash)"
432472
| `ccli set <TAB>` | Flags + namespace prefixes (one level at a time) |
433473
| `ccli config <TAB>` | Subcommands (`set`, `get`, `info`, `examples`, `completions`) |
434474
| `ccli config set <TAB>` | Config keys (`colors`, `theme`) |
435-
| `ccli data export <TAB>` | `entries`, `aliases`, `all` |
475+
| `ccli data export <TAB>` | `entries`, `aliases`, `confirm`, `all` |
436476

437477
### Scripting Tips
438478

@@ -464,12 +504,13 @@ ccli --debug get server.production
464504
| `get` | `g` | `[key]` | Retrieve entries or specific data |
465505
| `run` | `r` | `<keys...>` | Execute stored command(s) (`:` compose, `&&` chain) |
466506
| `find` | `f` | `<term>` | Find entries by key or value |
507+
| `edit` | `e` | `<key>` | Open an entry's value in `$EDITOR` |
467508
| `remove` | `rm` | `<key>` | Remove an entry and its alias |
468509
| `rename` | `rn` | `<old> <new>` | Rename an entry key or alias |
469-
| `config` | | `[setting] [value]` | View or change configuration settings |
510+
| `config` | | `<subcommand>` | View or change configuration settings |
470511
| `data` | | `<subcommand>` | Manage stored data (export, import, reset) |
471512

472-
**Config subcommands:** `info`, `examples`, `completions <bash\|zsh\|install>`
513+
**Config subcommands:** `set <key> <value>`, `get [key]`, `info`, `examples`, `completions <bash\|zsh\|install>`
473514

474515
**Data subcommands:** `export <type>`, `import <type> <file>`, `reset <type>`
475516

@@ -485,10 +526,10 @@ CodexCLI includes a built-in [Model Context Protocol](https://modelcontextprotoc
485526
claude mcp add codexcli -- node /absolute/path/to/dist/mcp-server.js
486527
```
487528

488-
If you installed CodexCLI globally, you can also use:
529+
If you installed from source via `npm install -g .`, you can also use:
489530

490531
```bash
491-
claude mcp add codexcli -- ccli-mcp
532+
claude mcp add codexcli -- cclid-mcp
492533
```
493534

494535
#### Claude Desktop
@@ -510,14 +551,14 @@ Add the following to your Claude Desktop MCP config file:
510551

511552
| Tool | Description |
512553
|---|---|
513-
| `codex_set` | Set an entry in the data store (key + value, optional alias) |
514-
| `codex_get` | Retrieve entries (specific key, subtree, or all; flat or tree format) |
554+
| `codex_set` | Set an entry (key + value, optional alias, optional encrypt + password) |
555+
| `codex_get` | Retrieve entries (specific key, subtree, or all; optional decrypt + password) |
515556
| `codex_remove` | Remove an entry or alias by key |
516557
| `codex_search` | Search entries by key or value (case-insensitive) |
517558
| `codex_alias_set` | Create or update an alias for a dot-notation path |
518559
| `codex_alias_remove` | Remove an alias |
519560
| `codex_alias_list` | List all defined aliases |
520-
| `codex_run` | Execute a stored command (with optional dry-run mode) |
561+
| `codex_run` | Execute a stored command (dry-run, force to skip confirm check) |
521562
| `codex_config_get` | Get one or all configuration settings |
522563
| `codex_config_set` | Set a configuration setting (colors, theme) |
523564
| `codex_export` | Export data and/or aliases as JSON text |

0 commit comments

Comments
 (0)