Skip to content

feat: new command#47

Merged
shikaan merged 22 commits intomainfrom
feat/34-new-command
Mar 13, 2026
Merged

feat: new command#47
shikaan merged 22 commits intomainfrom
feat/34-new-command

Conversation

@shikaan
Copy link
Copy Markdown
Owner

@shikaan shikaan commented Mar 11, 2026

This change adds a new/create command to create an empty database.

Closes #34

TODO

  • Add short and long descriptions of the command
  • Coalesce gokeepasslib calls into one kdbx call
  • Use the unified call in tests too
  • Support key file flows as well
  • Generate documentation

@shikaan shikaan force-pushed the feat/34-new-command branch from 16b997d to 47f9e2f Compare March 11, 2026 07:44
@shikaan shikaan force-pushed the feat/34-new-command branch from 822fc4f to 94e0bdd Compare March 11, 2026 19:42
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new create/new CLI command to create an empty KeePass (.kdbx) database, and refactors database initialization/opening so tests and commands use a unified kdbx API.

Changes:

  • Introduce create/new command with interactive passphrase creation and optional immediate TUI open.
  • Refactor pkg/kdbx to use OpenFromPath + NewFromFile and centralize credential setup via SetPasswordAndKey.
  • Update CLI/TUI tests and improve error message clarity across several packages.

Reviewed changes

Copilot reviewed 17 out of 17 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
tui/app.go Tweaks TUI startup error message formatting.
test/tui_test.go Updates E2E TUI fixture creation to use pkg/kdbx APIs.
test/cli_test.go Updates fixture DB creation; adds help/arg-validation tests for create/new.
pkg/log/log.go Adjusts error messages during log initialization.
pkg/kdbx/kdbx_test.go Updates tests for Database.file pointer change.
pkg/kdbx/kdbx.go Adds OpenFromPath/NewFromFile, credential helper, and updates save/unlock internals.
pkg/credentials/credentials.go Adds MakePassphrase and moves secret reading to pkg/cli.
pkg/clipboard/clipboard.go Improves clipboard error message.
pkg/cli/cli.go Adds shared CLI helpers for secret input and confirmations.
main.go Corrects error namespace for unexpected errors.
cmd/root.go Registers new Create command.
cmd/open.go Switches to OpenFromPath and improves error messages.
cmd/list.go Switches to OpenFromPath.
cmd/create.go New create/new command implementation.
cmd/copy.go Switches to OpenFromPath and improves error messages.
CONTRIBUTING.md Adds manual test checklist for create/new flow.
.vimspector.json Adds a Vimspector debug configuration.
Comments suppressed due to low confidence (2)

pkg/kdbx/kdbx.go:50

  • OpenFromPath opens the file and, if UnlockWithPasswordAndKey returns an error (wrong password/key, decode error, etc.), returns without closing the file descriptor. Consider ensuring the file is closed on all error paths (e.g., close before returning on unlock failure).
func OpenFromPath(filepath, password, keypath string) (*Database, error) {
	file, err := os.Open(filepath)

	if err != nil {
		return nil, errors.MakeError("Cannot open "+filepath+": "+err.Error(), "kdbx")
	}

	kdbx, err := NewFromFile(file)
	if err != nil {
		return nil, errors.MakeError("Cannot open "+filepath+": "+err.Error(), "kdbx")
	}

	if err := kdbx.UnlockWithPasswordAndKey(password, keypath); err != nil {
		return nil, err
	}

pkg/kdbx/kdbx.go:353

  • unlock() calls d.Database.UnlockProtectedEntries() but ignores its returned error. Since UnlockProtectedEntries can fail (and is checked elsewhere in SaveAndUnlockEntries), errors here would be silently ignored and could leave protected values locked. Consider capturing and returning the error.
	if err := gokeepasslib.NewDecoder(d.file).Decode(&d.Database); err != nil {
		return errors.MakeError("Cannot unlock database: "+err.Error(), "kdbx")
	}

	d.Database.UnlockProtectedEntries()
	return nil

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 18 out of 18 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (1)

pkg/kdbx/kdbx.go:49

  • OpenFromPath() opens the file with os.Open, but on error paths after that (e.g., unlock failure), the file handle is never closed. This can leak descriptors and may keep the file locked on some platforms. Consider closing file if NewFromFile or UnlockWithPasswordAndKey returns an error (or have Database take ownership only on success).
	file, err := os.Open(filepath)

	if err != nil {
		return nil, errors.MakeError("Cannot open "+filepath+": "+err.Error(), "kdbx")
	}

	kdbx, err := NewFromFile(file)
	if err != nil {
		return nil, errors.MakeError("Cannot open "+filepath+": "+err.Error(), "kdbx")
	}

	if err := kdbx.UnlockWithPasswordAndKey(password, keypath); err != nil {
		return nil, err
	}

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@shikaan shikaan marked this pull request as ready for review March 12, 2026 20:51
@shikaan shikaan requested a review from Copilot March 12, 2026 20:51
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 19 out of 19 changed files in this pull request and generated 9 comments.

Comments suppressed due to low confidence (1)

pkg/kdbx/kdbx.go:49

  • OpenFromPath opens a file handle but does not close it if UnlockWithPasswordAndKey fails (e.g., wrong password / decode error). This can leak file descriptors in repeated opens; consider closing file on error (or adding a defer that closes unless ownership is transferred successfully).
func OpenFromPath(filepath, password, keypath string) (*Database, error) {
	file, err := os.Open(filepath)

	if err != nil {
		return nil, errors.MakeError("Cannot open "+filepath+": "+err.Error(), "kdbx")
	}

	kdbx, err := NewFromFile(file)
	if err != nil {
		return nil, errors.MakeError("Cannot open "+filepath+": "+err.Error(), "kdbx")
	}

	if err := kdbx.UnlockWithPasswordAndKey(password, keypath); err != nil {
		return nil, err
	}

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@shikaan shikaan merged commit 7bfea5f into main Mar 13, 2026
1 check passed
@shikaan shikaan deleted the feat/34-new-command branch March 13, 2026 18:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

new/create command

2 participants