A monorepo management tool for the agentic ages
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Add tangled.org tree links to README.md generation

Parse origin remote URL to generate hyperlinks to branch trees on
tangled.org. Links are URL-encoded (/ -> %2F) and added to:
- Project names (linking to project/* branches)
- Package names (linking to opam/patches/* branches)
- Git repo names (linking to git/patches/* branches)
- Merged Into columns (linking to project branches)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

+44 -5
+44 -5
bin/main.ml
··· 1670 1670 tm.Unix.tm_hour tm.Unix.tm_min tm.Unix.tm_sec 1671 1671 in 1672 1672 1673 + (* Get tangled.org base URL from origin remote *) 1674 + let tangled_base = 1675 + match Unpac.Git.remote_url ~proc_mgr ~cwd:git "origin" with 1676 + | None -> None 1677 + | Some url -> 1678 + (* Parse git@git.recoil.org:user/repo or similar *) 1679 + let url = String.trim url in 1680 + (* Handle git@host:user/repo format *) 1681 + if String.starts_with ~prefix:"git@" url then 1682 + match String.index_opt url ':' with 1683 + | None -> None 1684 + | Some colon_pos -> 1685 + let path = String.sub url (colon_pos + 1) (String.length url - colon_pos - 1) in 1686 + (* Strip .git suffix if present *) 1687 + let path = if String.ends_with ~suffix:".git" path then 1688 + String.sub path 0 (String.length path - 4) else path in 1689 + Some (Printf.sprintf "https://tangled.org/%s" path) 1690 + else None 1691 + in 1692 + 1693 + (* URL encode a branch name for tree URLs *) 1694 + let url_encode s = 1695 + let buf = Buffer.create (String.length s * 2) in 1696 + String.iter (fun c -> 1697 + match c with 1698 + | '/' -> Buffer.add_string buf "%2F" 1699 + | ' ' -> Buffer.add_string buf "%20" 1700 + | c -> Buffer.add_char buf c 1701 + ) s; 1702 + Buffer.contents buf 1703 + in 1704 + 1705 + (* Create a markdown link to a branch tree, or just the name if no base URL *) 1706 + let branch_link name branch = 1707 + match tangled_base with 1708 + | None -> name 1709 + | Some base -> Printf.sprintf "[%s](%s/tree/%s)" name base (url_encode branch) 1710 + in 1711 + 1673 1712 add "# Unpac Workspace Status\n\n"; 1674 1713 addf "_Last updated: %s_\n\n" timestamp; 1675 1714 ··· 1706 1745 else if wt_exists then "📂 worktree active" 1707 1746 else "✓" in 1708 1747 addf "| %s | %d | %d | %s |\n" 1709 - proj (List.length merged_opam) (List.length merged_git) status 1748 + (branch_link proj proj_branch) (List.length merged_opam) (List.length merged_git) status 1710 1749 ) project_names; 1711 1750 add "\n" 1712 1751 end; ··· 1732 1771 ) project_names in 1733 1772 1734 1773 let merged_str = if merged_into = [] then "-" 1735 - else String.concat ", " merged_into in 1774 + else String.concat ", " (List.map (fun p -> branch_link p ("project/" ^ p)) merged_into) in 1736 1775 1737 1776 let status = 1738 1777 if dirty then "⚠️ uncommitted" 1739 1778 else if has_wt then "📂 editing" 1740 1779 else "✓" in 1741 1780 1742 - addf "| %s | %d | %s | %s |\n" pkg patch_count merged_str status 1781 + addf "| %s | %d | %s | %s |\n" (branch_link pkg patches_branch) patch_count merged_str status 1743 1782 ) opam_packages; 1744 1783 add "\n" 1745 1784 end; ··· 1765 1804 ) project_names in 1766 1805 1767 1806 let merged_str = if merged_into = [] then "-" 1768 - else String.concat ", " merged_into in 1807 + else String.concat ", " (List.map (fun p -> branch_link p ("project/" ^ p)) merged_into) in 1769 1808 1770 1809 let status = 1771 1810 if dirty then "⚠️ uncommitted" 1772 1811 else if has_wt then "📂 editing" 1773 1812 else "✓" in 1774 1813 1775 - addf "| %s | %d | %s | %s |\n" repo patch_count merged_str status 1814 + addf "| %s | %d | %s | %s |\n" (branch_link repo patches_branch) patch_count merged_str status 1776 1815 ) git_repos; 1777 1816 add "\n" 1778 1817 end;