Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
b20b515
Fix README discrepancies found during code verification
claude Feb 21, 2026
7a12d81
Fix P0 bugs: stale help text, broken export, and wrong alias hint
claude Feb 21, 2026
0f1d328
Update package-lock.json bin entry ordering from npm install
claude Feb 21, 2026
40cda1f
Fix P1 issues: MCP confirm enforcement, Windows clipboard, file permi…
claude Feb 21, 2026
6c451dd
Mark P0 issues as fixed in ISSUES.md
claude Feb 21, 2026
1670a1d
Implement all 7 P2 missing core features
claude Feb 21, 2026
cfbe4b9
Add P3 feature request documentation for GitHub issue creation
claude Feb 21, 2026
766e3cc
Update README and CHANGELOG with all P0-P2 fixes
claude Feb 21, 2026
53cdbba
Update src/index.ts
seabearDEV Feb 21, 2026
b9b4081
Update src/utils/autoBackup.ts
seabearDEV Feb 21, 2026
44f50b1
Initial plan
Copilot Feb 21, 2026
9a261b7
Update CHANGELOG.md
seabearDEV Feb 21, 2026
14834cb
Update src/utils/autoBackup.ts
seabearDEV Feb 21, 2026
888b964
Initial plan
Copilot Feb 21, 2026
245ae58
Initial plan
Copilot Feb 21, 2026
d5a1112
Mask plaintext value in codex_set response when encrypt=true
Copilot Feb 21, 2026
02b1b84
Fix command injection vulnerability: use spawnSync with env var for t…
Copilot Feb 21, 2026
700141c
Replace busy-wait spin loop with Atomics.wait() in fileLock.ts
Copilot Feb 21, 2026
0bbe0ad
Add tests for codex_set encryption masking in MCP response
Copilot Feb 21, 2026
f092477
Merge pull request #3 from seabearDEV/copilot/sub-pr-2
seabearDEV Feb 21, 2026
812570c
Update src/commands/entries.ts
seabearDEV Feb 21, 2026
f15d1bb
Handle Windows shell and check editor exit status in spawnSync
Copilot Feb 21, 2026
ee15132
Merge pull request #5 from seabearDEV/copilot/sub-pr-2-another-one
seabearDEV Feb 21, 2026
83b4c59
Merge pull request #4 from seabearDEV/copilot/sub-pr-2-again
seabearDEV Feb 21, 2026
1d156e9
Fix 12 review issues: double resolveKey, missing completions, JSON in…
seabearDEV Feb 21, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,31 @@ All notable changes to this project will be documented in this file.

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

## [Unreleased]

### Added

- `edit` command (alias `e`) — open an entry's value in `$EDITOR` / `$VISUAL` with `--decrypt` support
- `--json` / `-j` flag on `get` and `find` for machine-readable JSON output
- Stdin piping for `set` — read value from stdin when piped (`echo "val" | ccli set key`)
- `confirm` as a standalone type for `data export`, `data import`, and `data reset`
- Advisory file locking (`fileLock.ts`) — all writes are lock-protected with stale-lock detection
- Auto-backup before destructive operations (`data reset`, non-merge `data import`) in `~/.codexcli/.backups/`
- MCP `codex_set`: `encrypt` and `password` parameters for encrypted storage
- MCP `codex_get`: `decrypt` and `password` parameters for encrypted retrieval
- MCP `codex_run`: `force` parameter to skip confirm check on protected entries
- MCP `codex_export`, `codex_import`, `codex_reset`: support for `confirm` data type
- Windows clipboard support via `clip` command

### Fixed

- `showExamples()` referenced non-existent flags `-k`, `-v`, `-e` — now uses valid flags
- `showHelp()` config signature and subcommands were incorrect — now shows `<subcommand>` with correct list
- `displayAliases` empty-state message referenced deleted command — now shows `set <key> <value> -a <alias>`
- `data export all -o <file>` overwrote the same file three times — filenames now suffixed with type
- MCP `codex_run` ignored `confirm` metadata — now checks confirm before executing
- Data files used default permissions (0644) — now use 0600; directories use 0700

## [0.1.0] - 2026-02-20

### Added
Expand Down
142 changes: 142 additions & 0 deletions ISSUES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
# CodexCLI — Known Issues & Missing Features

Comprehensive audit of bugs, inconsistencies, and missing features.

---

## P0 — Bugs (FIXED)

### 1. ~~`showExamples()` references non-existent flags `-k`, `-v`, `-e`~~ FIXED

**File:** `src/formatting.ts`

Examples now use valid flags: `get -a` (aliases only), `find prod -e` (entries only), `find ip -a` (aliases only), `find server -t` (tree).

### 2. ~~`showHelp()` config signature and subcommands are wrong~~ FIXED

**File:** `src/formatting.ts`

Config line now shows `<subcommand>` and SUBCOMMANDS section includes `set, get, info, examples, completions`.

### 3. ~~`displayAliases` empty-state message references deleted command~~ FIXED

**File:** `src/commands/helpers.ts`

Message now shows the correct command: `set <key> <value> -a <alias>`.

### 4. ~~`data export all -o <file>` overwrites same file three times~~ FIXED

**File:** `src/commands/data-management.ts`

When `type === 'all'` and `-o` is specified, filenames are suffixed with the type (e.g., `backup-entries.json`, `backup-aliases.json`, `backup-confirm.json`).

---

## P1 — Security & Platform Gaps (FIXED)

### 5. ~~MCP `codex_run` ignores `confirm` metadata~~ FIXED

**File:** `src/mcp-server.ts`

`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.

### 6. ~~Windows clipboard is unsupported~~ FIXED

**File:** `src/utils/clipboard.ts`

Added `win32` platform support using `clip` command.

### 7. ~~Data files use default permissions (0644)~~ FIXED

**File:** `src/utils/atomicWrite.ts`, `src/utils/paths.ts`, `src/commands/data-management.ts`

- `atomicWriteFileSync` now writes files with mode `0o600` (owner read/write only)
- `ensureDataDirectoryExists` now creates directories with mode `0o700`
- Export files in `data-management.ts` also use mode `0o600`

---

## P2 — Missing Core Features (FIXED)

### 8. ~~No stdin piping for `set`~~ FIXED

`set` now reads from stdin when piped (non-TTY): `echo "value" | ccli set key`.

### 9. ~~No `edit` command (`$EDITOR` support)~~ FIXED

Added `edit` (alias `e`) command: `ccli edit <key>` opens the value in `$EDITOR`/`$VISUAL`. Supports `--decrypt` for encrypted entries.

### 10. ~~MCP has no encryption support (set/get)~~ FIXED

`codex_set` now accepts `encrypt` and `password` parameters. `codex_get` now accepts `decrypt` and `password` parameters.

### 11. ~~`confirm` is not a standalone export/import type~~ FIXED

`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`.

### 12. ~~No file locking for concurrent access~~ FIXED

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.

### 13. ~~No auto-backup before destructive operations~~ FIXED

Added `src/utils/autoBackup.ts`. Automatic backups are created in `~/.codexcli/.backups/` before `data reset` and non-merge `data import`.

### 14. ~~No `--json` output format~~ FIXED

Added `--json` / `-j` flag to `get` and `find` commands for machine-readable JSON output.

---

## P3 — Nice-to-Have Features

### 15. Fish/PowerShell shell completion

Only Bash and Zsh are supported. Fish and PowerShell users get no completions or wrapper.

### 16. No `copy`/`cp` command

Cannot duplicate an entry to a new key without get + set.

### 17. No import preview/diff

`data import --merge` silently overwrites conflicting keys with no way to preview what will change.

### 18. No advanced search (regex, boolean operators)

`find` only does case-insensitive substring matching. No regex, field-specific search, or boolean operators.

### 19. No backup rotation / automatic backup management

No built-in way to maintain a set of N recent backups.

### 20. No command output capture

`run` inherits stdio — no way to capture command output for chaining.

### 21. No change log / audit trail

No record of what was added, changed, or deleted over time.

### 22. No fuzzy finder integration

No `fzf` or similar interactive selection for keys.

### 23. No conditional interpolation

No `${ref:-default}` or `${ref:?error}` syntax for fallback values.

### 24. No batch operations

Cannot set multiple entries in one command.

---

## Summary

| Priority | Count | Description |
|----------|-------|-------------|
| **P0** | 4 | ~~Bugs showing incorrect info or causing data loss~~ ALL FIXED |
| **P1** | 3 | ~~Security and platform gaps~~ ALL FIXED |
| **P2** | 7 | ~~Missing core features~~ ALL FIXED |
| **P3** | 10 | Nice-to-have features |
65 changes: 53 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ A command-line information store for quick reference of frequently used data.
- [Searching](#searching)
- [Aliases](#aliases)
- [Renaming](#renaming)
- [Editing Data](#editing-data)
- [Removing Data](#removing-data)
- [Interpolation](#interpolation)
- [Encryption](#encryption)
Expand Down Expand Up @@ -41,7 +42,12 @@ CodexCLI is a command-line tool designed to help you store, organize, and retrie
- **Encryption**: Password-protect sensitive values
- **Search**: Find entries by searching keys or values
- **Tree Visualization**: Display nested data in a tree-like structure
- **Clipboard Integration**: Copy values directly to clipboard
- **Clipboard Integration**: Copy values directly to clipboard (macOS, Linux, Windows)
- **Inline Editing**: Open entries in `$EDITOR` / `$VISUAL` for quick edits
- **JSON Output**: Machine-readable `--json` flag on `get` and `find` for scripting
- **Stdin Piping**: Pipe values into `set` from other commands
- **Auto-Backup**: Automatic timestamped backups before destructive operations
- **File Locking**: Advisory locking prevents data corruption from concurrent access
- **Shell Tab-Completion**: Full tab-completion for Bash and Zsh (commands, flags, keys, aliases)
- **MCP Server**: Expose CodexCLI as a tool for AI agents (Claude Code, Claude Desktop) via the Model Context Protocol

Expand Down Expand Up @@ -84,6 +90,8 @@ ccli

### Install from Source

> **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.

Ensure npm's global binaries are in your PATH by adding the following to your shell profile (`.bashrc`, `.zshrc`, or equivalent):

```bash
Expand All @@ -98,7 +106,7 @@ npm run build
npm install -g .
```

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

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

# Remove the confirmation requirement from an entry
ccli set commands.deploy --no-confirm

# Pipe a value from stdin
echo "my value" | ccli set mykey

# Pipe from another command
curl -s https://api.example.com/token | ccli set api.token
```

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.
Expand Down Expand Up @@ -166,6 +180,9 @@ ccli get api.key -d
# Copy value to clipboard
ccli get server.ip -c

# Output as JSON (for scripting)
ccli get server --json

# Show aliases only
ccli get -a
```
Expand Down Expand Up @@ -218,6 +235,9 @@ ccli find ip -a

# Show results as a tree
ccli find server -t

# Output as JSON (for scripting)
ccli find prod --json
```

### Aliases
Expand Down Expand Up @@ -260,6 +280,18 @@ ccli rename -a oldalias newalias
ccli rename server.old server.new --set-alias sn
```

### Editing Data

Open a stored value in your `$EDITOR` (or `$VISUAL`) for inline editing:

```bash
# Edit an entry in your default editor
ccli edit server.production.ip

# Edit an encrypted entry (decrypts before editing, re-encrypts on save)
ccli edit api.key --decrypt
```

### Removing Data

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

# Export everything
ccli data export all -o backup.json
# Export with pretty-printed JSON
ccli data export entries --pretty

# Export confirm metadata
ccli data export confirm

# Export everything (entries, aliases, confirm metadata)
ccli data export all

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

> **Auto-backup:** Before destructive operations (`data reset`, non-merge `data import`), CodexCLI automatically creates a timestamped backup in `~/.codexcli/.backups/`.

### Shell Wrapper

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.
Expand Down Expand Up @@ -432,7 +472,7 @@ eval "$(ccli config completions bash)"
| `ccli set <TAB>` | Flags + namespace prefixes (one level at a time) |
| `ccli config <TAB>` | Subcommands (`set`, `get`, `info`, `examples`, `completions`) |
| `ccli config set <TAB>` | Config keys (`colors`, `theme`) |
| `ccli data export <TAB>` | `entries`, `aliases`, `all` |
| `ccli data export <TAB>` | `entries`, `aliases`, `confirm`, `all` |

### Scripting Tips

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

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

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

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

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

```bash
claude mcp add codexcli -- ccli-mcp
claude mcp add codexcli -- cclid-mcp
```

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

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