84 lines
4.4 KiB
Markdown
84 lines
4.4 KiB
Markdown
# Plan — editable and deletable nodes
|
|
|
|
Ordered tasks for the `implement` stage. Inputs: `architecture/node-editing.md`,
|
|
stubs across the workspace, gates in `quality/node-editing.md`. Tests:
|
|
`devenv shell -- cargo test --workspace` (10 failing at plan time = the
|
|
target: 5 in tidaldy, 5 in cbd-tui). Use the session-local `CARGO_TARGET_DIR`
|
|
if `target/` contains artifacts owned by the repo owner.
|
|
|
|
## 1. Term-list mutations (tidaldy)
|
|
|
|
- [x] Implement `rename_search_term(old, new)`: under one write lock, if
|
|
`new` already exists remove the `old` slot (merge); else if `old`
|
|
exists replace it in place; else push `new` (stale-client
|
|
forgiveness). Implement `remove_search_term(term)`: `retain`
|
|
everything but `term`. Both poison-tolerant like
|
|
`register_search_term`, no await under the lock. **Verify**:
|
|
`rename_replaces_in_place_and_merges_duplicates` passes; gate "lock
|
|
discipline".
|
|
|
|
## 2. Provider rename/delete (tidaldy)
|
|
|
|
- [x] `rename_lib_node`: trim new title → `InvalidInput` if empty;
|
|
`parse_path(path)?` must be `TidalPath::SearchTerm(old)` else
|
|
`NotSupported`; decode old term, `rename_search_term`, return
|
|
`get_lib_node(join_path(parent, encode_segment(new)))`. **Verify**:
|
|
`rename_rejects_empty_titles_and_foreign_paths` passes (validation
|
|
before any network call).
|
|
- [x] `delete_lib_node`: `parse_path(path)?` must be `SearchTerm` else
|
|
`NotSupported`; decode + `remove_search_term` (idempotent); return
|
|
`get_lib_node(/tidal/search)`. **Verify**: `delete_rejects_foreign_paths`
|
|
and `delete_removes_terms_idempotently_and_returns_the_parent` pass.
|
|
- [x] Flag term children in the `Search` arm of `get_lib_node`:
|
|
`is_editable: true, is_deletable: true` via struct update. **Verify**:
|
|
`search_node_lists_created_terms` passes (extended assertion).
|
|
|
|
## 3. Server handlers (crabidy-server)
|
|
|
|
- [x] Replace the `todo!()` bodies of `rpc.rs
|
|
rename_library_node`/`delete_library_node`: record span fields,
|
|
bounded(1) rendezvous with the matching `ProviderCommand`, map errors
|
|
exactly like `create_library_node` (`NotSupported` →
|
|
`failed_precondition` with an operation-specific message,
|
|
`InvalidInput` → `invalid_argument`, rest → `internal`). **Verify**:
|
|
gates "error mapping" + "bounded rendezvous"; `cargo check`.
|
|
(Orchestrator routing and the command-loop arms were finalized at
|
|
stub time — re-read them against the gate rather than re-doing them.)
|
|
|
|
## 4. TUI library accessors + marker (cbd-tui)
|
|
|
|
- [x] Implement `Library::selected_editable` / `selected_deletable` from
|
|
`list_state.selected()` + the `UiItem` flags. **Verify**:
|
|
`edit_opens_the_overlay_prefilled_only_on_editable_selections`,
|
|
`delete_sends_only_for_deletable_selections`,
|
|
`rename_submit_sends_the_trimmed_new_title`,
|
|
`rename_cancels_and_emptied_buffers_send_nothing` pass (dispatch and
|
|
overlay logic already landed with the stubs).
|
|
- [x] Render the `[e]`/`[d]`/`[ed]` suffix for modifiable items in
|
|
`Library::render`, `COLOR_SECONDARY` like `[%]`. **Verify**:
|
|
`modifiable_items_are_marked_and_the_rename_overlay_is_labelled`
|
|
passes; gate "marked in UI".
|
|
|
|
## 5. TUI ↔ server wiring (cbd-tui)
|
|
|
|
- [x] `RpcClient::rename_library_node`: send the rpc, evict the old path and
|
|
the parent (`crabidy_core::parent_path`), insert + return the renamed
|
|
node. `delete_library_node`: send the rpc, evict the deleted path and
|
|
the parent, insert + return the returned parent node. **Verify**: gate
|
|
"cache eviction" (read; the cache is private, as with create).
|
|
- [x] `main.rs poll`: replace the `todo!()` arms — `RenameNode` calls
|
|
`rename_library_node`, `DeleteNode` calls `delete_library_node`; on
|
|
success `ReplaceLibraryNode(node)`, on failure `error!` and leave the
|
|
UI unchanged. **Verify**: gate "failures never panic".
|
|
|
|
## 6. End-to-end + gates sweep
|
|
|
|
- [x] Exercise the full path against the live API if the local tidal config
|
|
is available (create a term, rename it, delete it, confirm the parent
|
|
listing and that a queued search track still resolves a URL); note the
|
|
outcome in the summary. If unavailable, rely on the offline tests and
|
|
say so.
|
|
- [x] Sweep: no `todo!()` left (workspace grep), fmt + clippy + tests green,
|
|
every `quality/node-editing.md` box checked, docs updated where
|
|
behavior shifted. Append the outcome + deviations to `plan/summary.md`.
|