Accept legacy share links and report patch drift

Merged
JS
6d ago
+848-170

Older course pages link notes as https://hackmd.io/s/<shortId>, which the tools refused. A short link names no workspace, so it is now found by its shortId: with team_path only that team is searched, without one the personal notes and then every team, and a shortId found more than once comes back as candidates rather than a guess. A trailing /download (the published-copy address) is accepted too. Patch edits on hackmd_update_note now report title_drift the way pull and push do, since renaming a note's H1 by patch never renames the note.

Supporting that meant telling an omitted team_path from the personal workspace: tool inputs now hold Option<Workspace>, and resolve_note_ref decides once what "none given" means for each kind of reference, which removes the guards that had let push search only the tracked team for a short link. On the wire nothing changes: null, an omitted field and the older tagged {"kind": "personal"} default all still mean "none given", and the team_path schema is the same nullable string.

Verified with make check (407 unit tests plus the integration targets) and cargo clippy --all-targets --all-features -- -D warnings, both clean. Reviewed by Codex, Agy and Claude across two rounds plus /code-review and /simplify. Live suites were not run. Left out: running team listings concurrently (risks 429 bursts on accounts in many teams) and title_drift for whole-body content replacements.


Summary by cubic

Accepts legacy https://hackmd.io/s/<shortId> share links as note references in every tool and reports title_drift on patch edits in hackmd_update_note, which previously kept that rename mismatch silent.

Legacy share links

  • With team_path only that team is searched; without one, personal notes and then every team are searched, using the existing 60-second caches.
  • A shortId found in more than one workspace returns candidates, never a guess, and a team whose list fails fails the search with an error suggesting team_path.
  • A trailing /download is ignored, and push cross-checks a short link across all workspaces so a link naming another workspace's note is a tracking mismatch.
  • Tool inputs now hold Option<Workspace> so an omitted team_path differs from the personal workspace; resolve_note_ref decides once what "none given" means for each reference kind. On the wire nothing changes: null, omission, and the older tagged {"kind": "personal"} still mean none given.

Patch title drift

  • A patch that renames the front-matter title: or a leading H1 reports the implied title as title_drift, judged against the read-back's title like push does.
  • Drift is reported only when the body before the patch matched the listed title, so a heading kept apart on purpose and a first H1 added to a body that had none stay silent.