feat(commands): add /link and /attach structured stash commands - #135
Merged
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
Pull request overview
Adds durable, structured local storage for links and file attachments and exposes it via new /link and /attach slash commands, with TUI autocomplete and user-facing docs updates.
Changes:
- Introduces
claurst-core::stashSQLite-backed store for link/attachment metadata and attachment file copies under the user config dir. - Registers
/linkand/attachcommands (with quote-aware flag parsing) and adds minimal tests for parsing + hosted-review refusal. - Updates TUI slash-command autocomplete list and documents the new commands in
docs/commands.md.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| src-rust/crates/tui/src/app.rs | Adds attach/link to the slash-command autocomplete/help list. |
| src-rust/crates/core/src/stash.rs | New SQLite stash store implementation + unit tests for core stash behaviors. |
| src-rust/crates/core/src/lib.rs | Exposes the new stash module from claurst-core. |
| src-rust/crates/commands/src/lib.rs | Implements /link + /attach, arg parsing helpers, command registration, and basic tests. |
| docs/commands.md | Documents /link and /attach and updates the TOC entry. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| session_id: session_id.map(str::to_string), | ||
| created_at_ms: Self::now_ms(), | ||
| }; | ||
| self.insert(&item)?; |
Comment on lines
+337
to
+348
| let item = self.get(id_prefix, kind)?; | ||
| self.conn | ||
| .execute("DELETE FROM stash_items WHERE id = ?1", [&item.id]) | ||
| .map_err(|e| StashError::Db(e.to_string()))?; | ||
| if item.kind == StashKind::Attachment { | ||
| let stored = Path::new(&item.value); | ||
| let _ = std::fs::remove_file(stored); | ||
| if let Some(dir) = stored.parent() { | ||
| let _ = std::fs::remove_dir(dir); | ||
| } | ||
| } | ||
| Ok(item) |
Comment on lines
+262
to
+264
| pub fn list(&self, filter: &StashFilter) -> Result<Vec<StashItem>, StashError> { | ||
| let mut items = self.query_all()?; | ||
| items.retain(|item| { |
| /link remove <id> — delete a link | ||
| ``` | ||
|
|
||
| `/link list` shows each entry's short id, save date, title, URL, and tags. `--project` limits the listing to links saved from the current repository. The stash is a personal local store and is disabled in [hosted review mode](configuration#hosted-review-mode). |
Comment on lines
+10237
to
+10241
| async fn execute(&self, args: &str, ctx: &mut CommandContext) -> CommandResult { | ||
| if let Some(refusal) = stash_hosted_refusal(ctx) { | ||
| return refusal; | ||
| } | ||
| let (positional, flags) = parse_stash_args(args); |
Member
Author
|
Addressed the review in ec913a6 and bea1f8b:
Not changed: |
Adds a durable, structured store for links and file attachments: - New core module `stash`: SQLite-backed store at ~/.coven-code/stash.sqlite with kind, title, note, tags, project, and session metadata. Attachments are copied into ~/.coven-code/attachments/<id>/<filename> (full-uuid directory) so the stored copy survives the original moving or being deleted; lookups and removals are kind-scoped so /link cannot resolve or delete an attachment id (and vice versa). - New slash commands /link (add/list/search/remove) and /attach (add/list/search/show/remove) with quote-aware argument parsing so paths and titles containing spaces work; unquoted attach paths with spaces also resolve. - Both commands refuse to run in hosted review mode: the stash is a personal local store and must not mix into hosted tenant contexts. - Registered in the command registry and TUI autocomplete; documented in docs/commands.md. Verified with cargo fmt, check, clippy -D warnings, workspace tests, and a live TUI smoke test (quoted-path attach, kind-scoped removal, stored-copy cleanup). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…mmands /attach now sorts first in the palette, pushing /config below the visible window on the initial capture. Anchor the open check on /clear and assert /attach, /clear, and /compact instead; the /config filter step still covers /config. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Review follow-ups on the /link //attach stash: - add_attachment removes the stored copy if the DB insert fails, so a locked/full database cannot leave orphaned files behind. - remove() deletes the stored copy before the DB row; a filesystem failure keeps the row for retry, while an already-missing copy does not block removal. - Fix the hosted-review docs link to use the ./configuration.md form. - Add an end-to-end /link //attach round-trip test against a temp home covering quoted paths with spaces, kind-scoped removal, and stored copy cleanup. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
scan_buffer_for_urls consults COVEN_CODE_NO_HYPERLINKS, and enabled_respects_env_var mutates that variable while sibling osc8 tests run in parallel, so scan assertions randomly saw an empty hit list. Point the scan tests at the env-independent scan_buffer; the env gate keeps its own dedicated test. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
/linkand/attachslash commands backed by a new structured stash store, so links and file attachments can be saved, tagged, searched, and managed durably across sessions.Context
claurst-core::stashmodule,/link+/attachcommands, TUI autocomplete entries, docs.Changes
core/stash.rs(new): SQLite store at~/.coven-code/stash.sqlite(rusqlite, matching the goal-store pattern) with kind (link/attachment), value, original path, title, note, tags, project, session, and timestamp. Attachments are copied into~/.coven-code/attachments/<full-uuid>/<filename>so the stored copy survives the original moving; removal deletes the row plus the stored copy and its directory. Lookups/removals accept an id prefix and are kind-scoped; ambiguous prefixes are rejected.commands/lib.rs:LinkCommand(/link [add] <url>,list [--tag|--project],search,remove) andAttachCommand(/attach [add] <path>,list,search,show,remove), registered in the command registry. Quote-aware argument tokenizer (--title "API spec", quoted paths); unquoted attach paths with spaces also resolve by joining positionals.~and relative paths resolve against home/cwd. Both commands refuse to run in hosted review mode.tui/app.rs:attach/linkautocomplete entries (alphabetical, keepsprompt_slash_commands_covers_registrygreen).docs/commands.md:/linkand/attachreference sections plus ToC entry.Code-review findings addressed before commit (reviewed via the code-review agent):
get/removeso/link removecan never delete an attachment's stored file (High).Validation
git diff --check— cleancargo fmt --all— cleancargo check --workspace— clean, no warningscargo clippy --workspace --all-targets -- -D warnings— cleancargo test --workspace— all green (10 new stash store tests, 8 new command tests, tui autocomplete coverage test)/attach "/tmp/stash smoke/my file.txt" --title "Quoted title"stores the copy under the full-uuid dir;/link remove <attachment-id>correctly refuses (no stash item matches);/attach removedeletes the row and stored copy. Test artifacts cleaned up.PR Readiness
/attach addtreats every positional afteraddas one path; a file literally namedlist/show/removeneeds/attach add <name>. Stash content is never loaded into prompts — future work could add/link use <id>-style context injection.