Commit graph

13 commits

Author SHA1 Message Date
Claude f6c8dfc951
fix(cli): create task-edit scratch file with mode 0600 on unix
onyx task edit wrote the task body to /tmp/onyx-<uuid>.md with the
default umask, leaving it world-readable on shared multi-user systems
for the duration of the editor session. Open with O_CREAT|O_TRUNC +
mode 0600 via OpenOptionsExt on unix; Windows keeps the existing
behaviour since unix-style mode bits don't apply.
2026-04-17 16:28:20 +00:00
Claude 8a81f05492
fix(cli): print clean error chain instead of anyhow Debug with backtrace
When RUST_BACKTRACE was set in the environment, every user-facing error
dumped a 20-line Rust backtrace at the user — e.g. running 'onyx list
show' with no workspace gave them a stack trace through anyhow, clap,
and libc start. Replace 'fn main() -> Result' with an explicit error
printer that walks the anyhow cause chain using Display, and exits 1.
Programming-bug panics still surface through the default panic handler.
2026-04-17 16:16:52 +00:00
Claude 433a950418
fix(cli): accept workspace name or UUID, auto-select on first add
Three related CLI bugs found during smoke testing:

1. `get_repository` used `config.get_workspace(name)` which expects the
   UUID string, so `onyx list create -w dev` or `onyx task add -w dev`
   always failed with "Workspace 'dev' not found". Unified CLI resolution
   into a single `resolve_workspace()` helper that accepts either the
   display name or the UUID; removed sync.rs's duplicated local copy.

2. `workspace switch`/`remove`/`retarget`/`migrate` only accepted the
   display name — the error message even suggested "Use the workspace ID
   instead" on ambiguous names, but IDs were then rejected. Updated
   `resolve_name` to try the map key first.

3. `onyx workspace add` never set `current_workspace`, so the very next
   command failed with "No workspace set. Use 'onyx init'..." even
   though a workspace was just created. Now sets the new workspace as
   current whenever none was previously selected, and reports the fact.
   Updated the error message to point at the correct `workspace add` /
   `workspace switch` commands instead of `init`.
2026-04-17 16:15:45 +00:00
Claude 85400b68bc
refactor: extract find_task helper to deduplicate CLI task search
The complete(), delete(), and edit() functions each had an identical
loop searching for a task by ID across all lists. Extract a shared
find_task() helper that returns the list ID and task.

https://claude.ai/code/session_013ooJht2HrZUTXgNJFU79cV
2026-04-16 07:27:16 +00:00
Claude 1ad6fddda6
refactor: deduplicate CLI group enable/disable into single function
The enable() and disable() functions were identical except for the
boolean parameter and output message. Extract shared set_grouping()
helper.

https://claude.ai/code/session_013ooJht2HrZUTXgNJFU79cV
2026-04-16 07:26:30 +00:00
Tristan Michael 9ed84690ac Rename due_date to date across codebase
The kebab menu and docs referred to a task "due date" but the field was
just a date; this change renames due_date/group_by_due_date and related
identifiers to date/group_by_date across Rust, TypeScript, Svelte, CLI,
docs and tests to keep terminology consistent. Updates include
API/command names, storage/models, repository methods, UI text, JS
variables and builder/parse functions so code, tests and documentation
all use "date" semantics.
Preserve old "group_by_due_date" field name

Add serde alias to ListMetadata.group_by_date so older .listdata.json
files that used the previous field name (group_by_due_date) can still be
deserialized correctly. This fixes serialization/deserialization issues
encountered at /home/trztn/Documents/Onyx and
/var/home/trztn/Nextcloud/Onyx.
the frontmatter due should be date... I don't want due anywhere

- Renamed `TaskFrontmatter.due` → `TaskFrontmatter.date`; YAML key on disk is now `date:` instead of `due:`
- Added `#[serde(alias = "due")]` so existing task files with `due:` frontmatter still deserialize correctly
- Updated google_tasks.rs to write `date:` instead of `due:` in generated YAML
- Renamed CLI `--due` flag to `--date`; updated function signature and display string "Due:" → "Date:"
Remove serde aliases and rename due→date

Drop backwards-compat aliases and update frontmatter/metadata to use the
canonical "date"/"group_by_date" fields. The aliases for
group_by_due_date and due were removed to avoid maintaining
backward-compatibility and to reflect the current schema. Updated
storage types to rename the fields and adjusted serialization attributes
so YAML/JSON frontmatter and .listdata.json files now use group_by_date
and date consistently.
2026-04-14 07:36:10 -07:00
Claude 85748f4c95
Audit fixes: panic safety, path hardening, code quality
- Replace 2 production unwrap() calls in workspace.rs with proper error
  handling to prevent panics on inconsistent state
- Add AppState::save_config() helper to eliminate 11 duplicated
  save_to_file patterns in Tauri lib.rs
- Log file watcher errors instead of silently swallowing them
- Harden path traversal check in storage.rs: re-verify after
  canonicalization to catch symlink escapes
- Add Windows reserved device name handling (CON, NUL, etc.) to
  sanitize_filename
- Clean up stale .tmp files from interrupted atomic writes on startup

All 107 core tests pass.

https://claude.ai/code/session_01EnSrQsowc64rAwzD9BnJpc
2026-04-06 10:41:03 +00:00
Tristan Michael 5e33416b22 Slim task frontmatter: remove timestamps, add version counter + self-healing dedup
Remove created_at/updated_at from Task struct and frontmatter. Add a
version counter (u64) that increments on every write, defaults to 1 for
old files. list_tasks now groups by UUID and auto-deletes stale
duplicates (keeping highest version), preventing sync-induced dupes from
surfacing in the UI. has_time and parent are omitted from frontmatter
when false/null.

Update CLI, Tauri frontend types, and Svelte components to match.
2026-04-05 19:22:10 -07:00
Tristan Michael 50d859ef80 Refactor workspaces to use UUID keys
Change workspace identifiers from display names to UUID strings so
multiple workspaces can share the same display name. WorkspaceConfig now
stores a name field; add_workspace returns a generated UUID. Update all
CLI, Tauri commands, frontend stores and screens, WebDAV managed
directories, and tests to use/resolve workspace IDs; add helpers
find_by_name/resolve_name to map display names to IDs when needed. This
removes duplicate-name checks, avoids filesystem conflicts, and
preserves display names while using stable unique IDs internally.
2026-04-05 14:58:31 -07:00
Tristan Michael be6b8d0d90 security: update callers for hardened credential API
- Handle Result from WebDavClient::new in CLI sync, core sync, and Tauri
- Unwrap Zeroizing<String> at Tauri serialization boundary
- Use .as_str() for basic_auth calls with Zeroizing<String> fields

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 10:11:40 -07:00
Tristan Michael fa1125bfeb fix: harden core data integrity — move_task rollback, path traversal, migration safety
Add rollback to move_task: if delete-from-source fails after write-to-
destination, clean up the duplicate. Reject list names with path separators
or '..' to prevent traversal; canonicalize() failures now return errors
instead of silently falling back to unchecked paths. Add validation and
rollback to CLI workspace migration: check destination is empty, track
moved files, and reverse on failure.
2026-04-02 09:37:43 -07:00
Tristan Michael 68f1bff93b fix: prevent path traversal, enable CSP, and harden URL domain extraction
Validate that resolved list paths stay within the workspace root to prevent
directory traversal via malicious list names. Enable Content Security Policy
in Tauri config instead of leaving it null. Fix CLI domain extraction to
strip userinfo (user:pass@) from URLs before using as keyring service name.
2026-04-02 09:35:38 -07:00
Tristan Michael 27363c8424 rename onyx-cli crate (formerly bevy-tasks-cli) 2026-03-31 09:47:02 -07:00