upstream(sync): Tier 1 CLI + dev-mcp — buzz://message links and ~ paths (#6359, #6271) - #300
Conversation
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
Runtime verification (binary-level, no relay)Built CLI —
|
| case | result |
|---|---|
--help shows link example + --channel optional |
✅ Usage requires only --event |
link only, no --channel |
✅ exit 0, relay got "#h":["9a1657ac-…"] from the link |
link + matching --channel |
✅ exit 0, identical filter |
link + conflicting --channel |
✅ exit 1, --channel … does not match the link's channel …, no relay request |
bare hex, no --channel |
✅ exit 1, --channel is required unless --event is a buzz://message link |
buzz://message?channel=&id= / ?id=<hex> / bare buzz://message |
✅ exit 1, invalid buzz://message link: … (expected …) |
buzz://thread?… (wrong host) |
✅ treated as bare id → exit 1 (hex validation), never sent |
percent-encoded link (%2D) |
✅ relay got decoded UUID |
link vs dead relay 127.0.0.1:1 |
✅ exit 2 network_error (resolution succeeded; 1 vs 2 distinguished) |
regression --channel + --event <hex> |
✅ exit 0, correct #h/#e |
$ buzz --format compact messages thread --event 'buzz://message?channel=9a1657ac-f7aa-5db0-b632-d8bbeb6dfb50&id=c3b589fa…be1dd1&thread=71d67180…b9224'
[]
[exit=0]
# fake relay received (link's thread= hex appears nowhere):
POST /query
[{"#e":["c3b589fa…be1dd1"],"#h":["9a1657ac-f7aa-5db0-b632-d8bbeb6dfb50"],
"kinds":[9,40002,40003,40008,45003],"limit":100},
{"ids":["c3b589fa…be1dd1"],"limit":1}]
$ buzz messages thread --channel 00000000-0000-0000-0000-000000000000 --event '<same link>'
{"error":"user_error","message":"--channel 00000000-0000-0000-0000-000000000000 does not match the link's channel 9a1657ac-f7aa-5db0-b632-d8bbeb6dfb50","retryable":false}
[exit=1]
Across the run the relay logged exactly 4 requests — one per success case; every input-error case
sent nothing.
dev-mcp — leading ~ expansion (all passed)
Server cwd = /home/ubuntu/pr300-evidence/mcp-workspace; probe file at $HOME/dev-mcp-tilde-probe-55306.txt.
→ read_file {"path":"~/dev-mcp-tilde-probe-55306.txt"}
← "~/dev-mcp-tilde-probe-55306.txt (lines 1-3 of 3)\n1:alpha\n2:beta\n3:gamma\n"
→ str_replace {"path":"~/dev-mcp-tilde-probe-55306.txt","old_str":"beta","new_str":"BETA"}
← "Replaced 1 occurrence in /home/ubuntu/dev-mcp-tilde-probe-55306.txt … -beta +BETA"
$ cat /home/ubuntu/dev-mcp-tilde-probe-55306.txt → alpha / BETA / gamma (real home file edited)
→ read_file {"path":"~"}
← error -32602 "not a regular file: /home/ubuntu" (expanded, not literal)
→ read_file {"path":"~nonexistentuser/dev-mcp-tilde-probe-55306.txt"}
← error -32602 "path not accessible: /home/ubuntu/pr300-evidence/mcp-workspace/~nonexistentuser/…"
(left literal — did NOT silently resolve under $HOME; probe file untouched)
→ read_file {"path":"notes.txt"} (regression)
← "1:workspace\n2:file\n" (still workdir-relative; no literal `~` dir created)
No failures and nothing unverified. Tested by Devin — session.
Desktop E2E failures are pre-existing on
|
|
Handover notes (stop-and-document): see the appended NOTES section in the PR description — same content as below. Handover NOTESDONEImplementation is complete and pushed (
Tests (TDD: RED captured before implementation, GREEN after; re-verified after the Gates run individually (never full Evidence (non-UI change, so full untruncated logs). Session-VM paths:
IN PROGRESSNothing. The working tree is clean; every file in the diff is committed and pushed. The only uncommitted artifact is an untracked, intentionally-not-committed suggested skill at TODO / NEXT
|
…xpand ~ in dev-mcp paths Ports upstream buzz block#6359 (message links) and block#6271 (tilde paths). buzz messages thread now accepts a Desktop "Copy link" buzz://message?channel=<uuid>&id=<hex> as --event, taking the channel from the link (--channel optional; must agree when both are given). The optional thread parameter is informational. buzz-dev-mcp read_file and str_replace expand a leading ~ to the home directory via the shared resolve_path seam; ~other/... is left alone. Signed-off-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-Authored-By: Oscar Le <oscar.lehuu@gmail.com>
1c3c071 to
e1aee5e
Compare
Summary
Ports two Tier 1 upstream Buzz changes (block#6359, block#6271) into Crew, without touching Crew-specific behaviour.
CLI —
buzz messages threadacceptsbuzz://messagelinks (block#6359). Newlinks::parse_message_linkmirrorsparseMessageLinkindesktop/src/features/messages/lib/messageLink.ts, so a Desktop "Copy link" can be pasted straight into--event:--channelbecomes optional (Option<String>); resolution is:dev-mcp — leading
~expansion (block#6271).read_fileandstr_replacesharepaths::resolve_path, so expansion goes in one place:~→ home,~/x→$HOME/x,~other/...deliberately left alone (no guessing another user's home), and the existing Windows MSYS conversion still runs after expansion. Addsdirs = "6"tobuzz-dev-mcp.Crew-specific behaviour preserved:
--evidence/evidence.rsuntouched, channel-first IA intact (#278) — the link only supplies the channel, it never bypasses channel scoping. No divergence from upstream intent found. Docs updated inAGENTS.mdandcrates/buzz-cli/README.md.Related issue
Fixes #284 (part of the Buzz 0.5.18 sync stack, meta #285).
Testing
TDD: tests written first (RED), then implementation (GREEN). Non-UI change, so evidence is full terminal logs (attached to the session message).
crates/buzz-cliandcrates/buzz-dev-mcpfailed to compile / failed on the new cases before implementation.cargo test -p buzz-cli --lib links+... commands::messages→ 38 passed, incl.thread_accepts_message_link_without_channel_flag,thread_link_conflicting_with_channel_flag_is_input_error,thread_link_with_thread_param_resolves_to_linked_event,thread_rejects_malformed_message_link,thread_without_channel_or_link_is_input_error,thread_keeps_explicit_channel_and_event_flags, and the pre-existingevidence_flag_*tests.cargo test -p buzz-dev-mcp→ 108 passed, incl.tilde_slash_expands_to_home_relative_path,tilde_alone_expands_to_home,named_user_tilde_is_not_expanded,tilde_is_left_alone_when_home_is_unknown,resolve_path_reads_home_relative_path_via_tilde.Gates (all run individually, not via
just ci):pnpm --filter buzz checkpnpm --filter buzz typecheckpnpm --filter buzz testjust _ensure-sidecar-stubs+just check-compilecargo clippy -p buzz-cli -p buzz-dev-mcp --all-targets -- -D warningscargo fmt -p buzz-cli -p buzz-dev-mcp -- --checkcommands/agents.rsjust test-unitPre-existing failures on
main, reproduced with this branch's changes stashed:buzz-clitests::command_inventory_is_stable,tests::subcommand_counts_are_stable,tests::subcommand_names_are_stable— the base already ships theorggroup andagents call, while the inventory snapshots still expect 23 groups / 5agentssubcommands. This PR adds no commands.buzz-dbmigration::tests::embedded_migrator_contains_consolidated_initial_schema.Not fixed here: out of #284's scope and owned by other issues in the sync stack.
Handover NOTES
DONE
Implementation is complete and pushed (
devin/issue-284-message-links-tilde-paths, HEAD1c3c0714c= impl commit5d4188807+ the parent session's merge ofmain).crates/buzz-cli/src/links.rs(MessageLink,is_message_link,parse_message_link),crates/buzz-cli/src/lib.rs(MessagesCmd::Thread.channel→Option<String>, help/examples),crates/buzz-cli/src/commands/messages.rs(resolve_thread_target).thread=is parsed but ignored for resolution; link/--channelmismatch is exit 1.crates/buzz-dev-mcp/src/paths.rs(expand_tildein the sharedresolve_pathseam, before the existing Windows/MSYS conversion),dirs = "6"incrates/buzz-dev-mcp/Cargo.toml+Cargo.lock, tool-description/schema docs insrc/lib.rsandsrc/read_file.rs.~and~/xexpand;~other/xdeliberately does not.AGENTS.md,crates/buzz-cli/README.md.--evidence/evidence.rsuntouched, channel-first IA (upstream(sync): Guardrail — preserve channel-first IA during 0.5.18 merge #278) intact — the link only supplies the channel, it never bypasses channel scoping.Tests (TDD: RED captured before implementation, GREEN after; re-verified after the
mainmerge):buzz-clilinks6 passed,buzz-clicommands::messages38 passed,buzz-dev-mcplib 108 passed.Gates run individually (never full
just ci):pnpm --filter buzz check,pnpm --filter buzz typecheck,pnpm --filter buzz test,just _ensure-sidecar-stubs+just check-compile,cargo clippy -p buzz-cli -p buzz-dev-mcp --all-targets -- -D warnings— all pass.cargo fmt -p buzz-cli -p buzz-dev-mcp -- --checkreports only a pre-existing diff in untouchedcrates/buzz-cli/src/commands/agents.rs.just test-unithas 4 failures that reproduce onmainwith this branch's changes stashed (3buzz-clicommand-inventory snapshots — base already shipsorg+agents call; 1buzz-dbmigration test).Evidence (non-UI change, so full untruncated logs). Session-VM paths:
/tmp—/home/ubuntu/evidence-284/:green-cli-links.log(6 passed),green-cli-messages.log(38 passed),green-devmcp.log(108 passed),gate-pnpm-check.log,gate-pnpm-typecheck.log,gate-sidecar-stubs.log,gate-check-compile.log,gate-clippy.log,gate-fmt-check.log(exit 1 only from the untouchedcommands/agents.rsdiff). Each file ends with the command'sexit=status./home/ubuntu/pr300-evidence/:cli-output.log,relay-requests.log,relay-requests-snapshot.log,mcp-output.log,mcp-stderr.log, plus the harness scriptscli-tests.sh,mcp-drive.py,fake_relay.py. These prove the resolvedchannel/eventactually sent in the outgoing relay filter (link-only and link+matching-channel resolve identically to the explicit flags; thethread=value never appears), that conflicting/malformed input exits 1 without contacting the relay while valid input against a dead relay exits 2, and that~/xreads/edits the real home-relative file while~nonexistentuser/xis left literal./tmpwipe (not re-runnable now without redoing the RED state): the originalred-cli.log/red-devmcp.log,gate-pnpm-test.log,gate-just-test-unit.log, and the base-branch reproduction logspreexisting-main-*.log,base-e2e-*.log. Their results are summarised above and in the earlier PR comment; the base-E2E reproduction commands are recorded there verbatim if anyone wants to re-run them.IN PROGRESS
Nothing. The working tree is clean; every file in the diff is committed and pushed. The only uncommitted artifact is an untracked, intentionally-not-committed suggested skill at
.agents/skills/cli-devmcp-blackbox/on the session VM (submitted separately as a skill suggestion, out of #284's scope).TODO / NEXT
Desktop Smoke E2E (1/2/3)andDesktop E2E Integration (1/2, 2/2)failed. This PR contains zerodesktop/files, and the identical specs/assertions fail on a cleanorigin/mainworktree — see the earlier comment on this PR for the reproduction.NuncioCrew Gateruns may also show as cancelled: the parent session is deliberately serialising CI because the Actions pool is saturated, which is expected and not a failure of this change.AGENTS.mdandCargo.lock, so trivial conflicts are possible if sibling sync PRs edit the same doc sections or add dependencies.MessagesCmd::Thread.channelis nowOption<String>— any sibling PR adding a call site must passOption. The stalebuzz-clicommand-inventory snapshots and thebuzz-dbmigration test will keep failingjust test-unituntil whichever issue owns them lands.Link to Devin session: https://app.devin.ai/sessions/18c28cba00b340f1b15aab7f44a72d62
Requested by: @oscarlehuu