Skip to content

feat: filesystem-first create command and default open-type config#90

Merged
Yakitrak merged 10 commits intomainfrom
feat/filesystem-first-create-open-type-config
Feb 18, 2026
Merged

feat: filesystem-first create command and default open-type config#90
Yakitrak merged 10 commits intomainfrom
feat/filesystem-first-create-open-type-config

Conversation

@Yakitrak
Copy link
Owner

@Yakitrak Yakitrak commented Feb 17, 2026

Summary

  • Filesystem-first create command: Notes are now written directly to disk — Obsidian does not need to be running. Supports --content, --overwrite, --append, and --open flags.
  • Default note folder: The create command reads .obsidian/app.json to determine the configured default folder for new notes. When the note name has no explicit path (no /), the note is placed in that folder. Falls back to vault root if config is missing.
  • Filesystem-first daily command: Daily notes are now created on disk instead of delegating to obsidian://daily. Reads .obsidian/daily-notes.json for folder, format (Moment.js date format), and template settings. Falls back to sensible defaults.
  • Configurable default_open_type: New set-default --open-type flag lets users choose between obsidian and editor as default open behavior. All editor-capable commands respect this setting.
  • --editor flag on all commands: Added --editor / -e flag to open and daily commands (previously only on search, search-content, create, move). All commands now support config fallback via default_open_type.
  • Refactored shared logic: Extracted resolveUseEditor() helper to eliminate duplicated editor flag boilerplate across 6 commands. Exported WriteNoteFile for reuse. Moved ApplyDefaultFolder to pkg/obsidian/config.go.
  • Dead code cleanup: Removed unused ObsCreateUrl, OnsDailyUrl, and createAction constants. Removed unsupported dd Moment.js token mapping.
  • Bug fix: --section flag now emits a warning when used with --editor (editors cannot navigate to markdown headings).

How to test

# Rebuild
go build -o bin/darwin/notesmd-cli .

# Set default open type
bin/darwin/notesmd-cli set-default --open-type editor

# Create note (uses default folder from .obsidian/app.json if configured)
bin/darwin/notesmd-cli create "test-note" --content "hello"

# Create note with explicit path (ignores default folder)
bin/darwin/notesmd-cli create "explicit/test-note" --content "hello"

# Daily note (reads .obsidian/daily-notes.json for folder/format/template)
bin/darwin/notesmd-cli daily
bin/darwin/notesmd-cli daily --editor

# Open note with editor
bin/darwin/notesmd-cli open "test-note" --editor

# Section warning when using editor
bin/darwin/notesmd-cli open "test-note" --editor --section "Heading"
# → prints: Warning: --section is ignored when using --editor

Test plan

  • All existing tests pass (except pre-existing WSL test failures)
  • New config reading tests (DefaultNoteFolder, ReadDailyNotesConfig, ApplyDefaultFolder, MomentToGoFormat)
  • New create tests (default folder from config, explicit path ignores default folder)
  • New daily tests (filesystem creation, configured folder, template, custom format, editor support)
  • DefaultOpenType / SetDefaultOpenType tests
  • README updated with new documentation

🤖 Generated with Claude Code

- create command now writes files directly to disk — Obsidian no longer
  needs to be running for note creation
- append, overwrite, and content flags are handled in Go; intermediate
  directories are created automatically
- opening after creation is optional: Obsidian URI or $EDITOR
- add default_open_type config field ('obsidian' | 'editor') to
  preferences.json
- set-default accepts --open-type flag to persist the preference; vault
  name argument is now optional so open type can be set independently
- cmd/create.go falls back to configured open type when --editor is not
  passed explicitly
- update README to document new create behaviour and set-default flags
- use cmd.Flags().Changed("editor") so --editor=false overrides
  default_open_type=editor
- remove dead ObsCreateUrl/createAction constants
- add unit tests for DefaultOpenType() and SetDefaultOpenType()
- add DefaultOpenType() to VaultManager interface and mock
- open, search, search-content, and move commands now fall back to
  the configured default_open_type when --editor is not explicitly passed
- open command gains --editor/-e flag and editor support in the action
- add tests for open action with UseEditor
- update README to list open alongside other editor-capable commands
…irst daily command

- Create command now reads .obsidian/app.json to determine the default
  folder for new notes (when note name has no explicit path)
- Daily command rewritten to create notes on disk instead of delegating
  to obsidian://daily URI, reading .obsidian/daily-notes.json for
  folder, date format, and template settings
- Daily command now supports --editor flag and respects default_open_type
- Added Moment.js to Go time format conversion for daily note naming
- Removed unused OnsDailyUrl constant
…ltFolder

- Extract resolveUseEditor() into cmd/editor.go to eliminate duplicated
  editor flag + config fallback boilerplate across 6 commands
- Export WriteNoteFile and reuse it in daily.go instead of raw os.WriteFile
- Move ApplyDefaultFolder from pkg/actions/create.go to
  pkg/obsidian/config.go where it belongs alongside DefaultNoteFolder
…terface type

- Emit a stderr warning when --section and --editor are both passed to
  the open command, since editors cannot navigate to markdown headings
- Remove the dd Moment.js token mapping which produced a static "Mo"
  literal instead of a dynamic weekday abbreviation (no Go equivalent)
- Change resolveUseEditor parameter from concrete *obsidian.Vault to
  obsidian.VaultManager interface for consistency and testability
…with args

- WriteNoteFile append path now checks f.Close() for errors instead of
  deferring it, preventing silent data loss on flush failure
- OpenInEditor now splits the EDITOR env var into command + arguments
  using strings.Fields, so values like "code -w" work correctly instead
  of being treated as a single binary name
- Bump version from v0.3.0 to v0.3.1
- Regenerate docs/usage.png with updated command descriptions
- print-default now also displays the configured default open type
…tests

- WSL vault path tests used vault names that didn't match path suffixes
  (getPathForVault uses HasSuffix on path, not map key lookup)
- Config obsidian path test didn't create the config file on disk, so
  os.Stat failed on non-Linux platforms
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.

1 participant

Comments